[APPHELP][APPHELP_APITEST] Add SdbGetFileAttributes + tests, based on the work of...
[reactos.git] / reactos / dll / appcompat / apphelp / sdbapi.c
index 1172121..fc6f2e3 100644 (file)
@@ -155,11 +155,6 @@ void SdbpHeapDeinit(void)
     HeapDestroy(g_Heap);
 }
 
-DWORD SdbpStrlen(PCWSTR string)
-{
-    return (lstrlenW(string) + 1) * sizeof(WCHAR);
-}
-
 static HANDLE SdbpHeap(void)
 {
     return g_Heap;
@@ -203,6 +198,94 @@ void SdbpFree(LPVOID mem
     HeapFree(SdbpHeap(), 0, mem);
 }
 
+DWORD SdbpStrlen(PCWSTR string)
+{
+    return (lstrlenW(string) + 1) * sizeof(WCHAR);
+}
+
+PWSTR SdbpStrDup(LPCWSTR string)
+{
+    PWSTR ret = SdbpAlloc(SdbpStrlen(string));
+    lstrcpyW(ret, string);
+    return ret;
+}
+
+
+BOOL WINAPI SdbpOpenMemMappedFile(LPCWSTR path, PMEMMAPPED mapping)
+{
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    FILE_STANDARD_INFORMATION FileStandard;
+    UNICODE_STRING FileName;
+
+    RtlZeroMemory(mapping, sizeof(*mapping));
+
+    if(!RtlDosPathNameToNtPathName_U(path, &FileName, NULL, NULL))
+    {
+        RtlFreeUnicodeString(&FileName);
+        return FALSE;
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+    Status = NtOpenFile(&mapping->file, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
+    RtlFreeUnicodeString(&FileName);
+
+    if (!NT_SUCCESS(Status))
+    {
+        SHIM_ERR("Failed to open file %S: 0x%lx\n", path, Status);
+        return FALSE;
+    }
+
+    Status = NtCreateSection(&mapping->section, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, 0, 0, PAGE_READONLY, SEC_COMMIT, mapping->file);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Special case */
+        if (Status == STATUS_MAPPED_FILE_SIZE_ZERO)
+        {
+            NtClose(mapping->file);
+            mapping->file = mapping->section = NULL;
+            return TRUE;
+        }
+        SHIM_ERR("Failed to create mapping for file: 0x%lx\n", Status);
+        goto err_out;
+    }
+
+    Status = NtQueryInformationFile(mapping->file, &IoStatusBlock, &FileStandard, sizeof(FileStandard), FileStandardInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        SHIM_ERR("Failed to read file info for file: 0x%lx\n", Status);
+        goto err_out;
+    }
+
+    mapping->mapped_size = mapping->size = FileStandard.EndOfFile.LowPart;
+    Status = NtMapViewOfSection(mapping->section, NtCurrentProcess(), (PVOID*)&mapping->view, 0, 0, 0, &mapping->mapped_size, ViewUnmap, 0, PAGE_READONLY);
+    if (!NT_SUCCESS(Status))
+    {
+        SHIM_ERR("Failed to map view of file: 0x%lx\n", Status);
+        goto err_out;
+    }
+
+    return TRUE;
+
+err_out:
+    if (!mapping->view)
+    {
+        if (mapping->section)
+            NtClose(mapping->section);
+        NtClose(mapping->file);
+    }
+    return FALSE;
+}
+
+void WINAPI SdbpCloseMemMappedFile(PMEMMAPPED mapping)
+{
+    NtUnmapViewOfSection(NtCurrentProcess(), mapping->view);
+    NtClose(mapping->section);
+    NtClose(mapping->file);
+    RtlZeroMemory(mapping, sizeof(*mapping));
+}
+
 /**
  * Converts specified tag into a string.
  *
@@ -213,7 +296,7 @@ void SdbpFree(LPVOID mem
 LPCWSTR WINAPI SdbTagToString(TAG tag)
 {
     /* lookup tables for tags in range 0x1 -> 0xFF | TYPE */
-    static const WCHAR table[9][0x31][25] = {
+    static const WCHAR table[9][0x32][25] = {
     {   /* TAG_TYPE_NULL */
         {'I','N','C','L','U','D','E',0},
         {'G','E','N','E','R','A','L',0},
@@ -284,7 +367,8 @@ LPCWSTR WINAPI SdbTagToString(TAG tag)
         {'I','n','v','a','l','i','d','T','a','g',0},
         {'I','n','v','a','l','i','d','T','a','g',0},
         {'C','O','N','T','E','X','T','_','T','A','G','I','D',0},
-        {'E','X','E','_','W','R','A','P','P','E','R',0}
+        {'E','X','E','_','W','R','A','P','P','E','R',0},
+        {'U','R','L','_','I','D',0}
     },
     {   /* TAG_TYPE_QWORD */
         {'T','I','M','E',0},
@@ -341,7 +425,8 @@ LPCWSTR WINAPI SdbTagToString(TAG tag)
         {'L','A','Y','E','R','_','D','I','S','P','L','A','Y','N','A','M','E',0},
         {'C','O','M','P','I','L','E','R','_','V','E','R','S','I','O','N',0},
         {'A','C','T','I','O','N','_','T','Y','P','E',0},
-        {'E','X','P','O','R','T','_','N','A','M','E',0}
+        {'E','X','P','O','R','T','_','N','A','M','E',0},
+        {'U','R','L',0}
     },
     {   /* TAG_TYPE_LIST */
         {'D','A','T','A','B','A','S','E',0},
@@ -368,7 +453,14 @@ LPCWSTR WINAPI SdbTagToString(TAG tag)
         {'A','C','T','I','O','N',0},
         {'L','O','O','K','U','P',0},
         {'C','O','N','T','E','X','T',0},
-        {'C','O','N','T','E','X','T','_','R','E','F',0}
+        {'C','O','N','T','E','X','T','_','R','E','F',0},
+        {'I','n','v','a','l','i','d','T','a','g',0},
+        {'I','n','v','a','l','i','d','T','a','g',0},
+        {'I','n','v','a','l','i','d','T','a','g',0},
+        {'I','n','v','a','l','i','d','T','a','g',0},
+        {'I','n','v','a','l','i','d','T','a','g',0},
+        {'I','n','v','a','l','i','d','T','a','g',0},
+        {'S','P','C',0}
     },
     {   /* TAG_TYPE_STRING */
         {'I','n','v','a','l','i','d','T','a','g',0}
@@ -400,10 +492,10 @@ LPCWSTR WINAPI SdbTagToString(TAG tag)
         TAG_REINSTALL_UPGRADE & 0xFF,
         1,
         TAG_MATCH_MODE & 0xFF,
-        TAG_EXE_WRAPPER & 0xFF,
+        TAG_URL_ID & 0xFF,
         TAG_FLAG_INSTALL & 0xFF,
-        TAG_EXPORT_NAME & 0xFF,
-        TAG_CONTEXT_REF & 0xFF,
+        TAG_URL & 0xFF,
+        TAG_SPC & 0xFF,
         1,
         TAG_APP_ID & 0xFF
     };