diff --git a/reactos/dll/win32/setupapi/cfgmgr.c b/reactos/dll/win32/setupapi/cfgmgr.c index 1fffe5be4c7..afc2d83ae21 100644 --- a/reactos/dll/win32/setupapi/cfgmgr.c +++ b/reactos/dll/win32/setupapi/cfgmgr.c @@ -66,9 +66,9 @@ static BOOL GuidToString(LPGUID Guid, LPWSTR String) lstrcpyW(&String[1], lpString); - String[0] = L'{'; - String[MAX_GUID_STRING_LEN - 2] = L'}'; - String[MAX_GUID_STRING_LEN - 1] = 0; + String[0] = '{'; + String[MAX_GUID_STRING_LEN - 2] = '}'; + String[MAX_GUID_STRING_LEN - 1] = UNICODE_NULL; RpcStringFreeW(&lpString); diff --git a/reactos/dll/win32/setupapi/devclass.c b/reactos/dll/win32/setupapi/devclass.c index 61215125c5f..36890a9fe49 100644 --- a/reactos/dll/win32/setupapi/devclass.c +++ b/reactos/dll/win32/setupapi/devclass.c @@ -276,7 +276,7 @@ SetupDiBuildClassInfoListExW( TRACE("Guid: %s\n", debugstr_w(szKeyName)); if (dwGuidListIndex < ClassGuidListSize) { - if (szKeyName[0] == L'{' && szKeyName[37] == L'}') + if (szKeyName[0] == '{' && szKeyName[37] == '}') szKeyName[37] = 0; UuidFromStringW(&szKeyName[1], @@ -472,7 +472,7 @@ SetupDiClassGuidsFromNameExW( TRACE("Guid: %s\n", debugstr_w(szKeyName)); if (dwGuidListIndex < ClassGuidListSize) { - if (szKeyName[0] == L'{' && szKeyName[37] == L'}') + if (szKeyName[0] == '{' && szKeyName[37] == '}') szKeyName[37] = 0; UuidFromStringW(&szKeyName[1], diff --git a/reactos/dll/win32/setupapi/devinst.c b/reactos/dll/win32/setupapi/devinst.c index 36b3f87f549..2b5ab0595d3 100644 --- a/reactos/dll/win32/setupapi/devinst.c +++ b/reactos/dll/win32/setupapi/devinst.c @@ -172,7 +172,7 @@ SetupDiCreateDeviceInfoListExW( IN PCWSTR MachineName OPTIONAL, IN PVOID Reserved) { - struct DeviceInfoSet *list; + struct DeviceInfoSet *list = NULL; DWORD size; DWORD rc; CONFIGRET cr; @@ -181,6 +181,12 @@ SetupDiCreateDeviceInfoListExW( TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent, debugstr_w(MachineName), Reserved); + if (Reserved != NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto cleanup; + } + size = FIELD_OFFSET(struct DeviceInfoSet, szData); if (MachineName) size += (strlenW(MachineName) + 3) * sizeof(WCHAR); @@ -205,7 +211,7 @@ SetupDiCreateDeviceInfoListExW( rc = RegConnectRegistryW(MachineName, HKEY_LOCAL_MACHINE, &list->HKLM); if (rc != ERROR_SUCCESS) { - SetLastError(rc); + SetLastError(ERROR_INVALID_MACHINENAME); goto cleanup; } @@ -493,7 +499,7 @@ CheckSectionValid( if (Fields[i]) { Fields[i]++; - *(Fields[i] - 1) = L'\0'; + *(Fields[i] - 1) = UNICODE_NULL; } } /* Take care of first 2 fields */ @@ -3422,7 +3428,7 @@ SetupDiInstallDevice( TRACE("Write information to driver key\n"); TRACE("DriverDate : '%u-%u-%u'\n", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear); TRACE("DriverDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description)); - TRACE("DriverVersion : '%u.%u.%u.%u'\n", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff); + TRACE("DriverVersion : '%ld.%ld.%lu.%ld'\n", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff); TRACE("InfPath : '%s'\n", debugstr_w(SelectedDriver->InfFileDetails->FileName)); TRACE("InfSection : '%s'\n", debugstr_w(SelectedDriver->Details.SectionName)); TRACE("InfSectionExt : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)])); diff --git a/reactos/dll/win32/setupapi/install.c b/reactos/dll/win32/setupapi/install.c index 498a6c30256..ddf83dec748 100644 --- a/reactos/dll/win32/setupapi/install.c +++ b/reactos/dll/win32/setupapi/install.c @@ -981,7 +981,7 @@ static BOOL needs_callback( HINF hinf, PCWSTR field, void *arg ) return SetupInstallServicesFromInfSectionExW(*(HINF*)hinf, field, info->flags, info->devinfo, info->devinfo_data, info->reserved1, info->reserved2); default: - ERR("Unknown info type %ld\n", info->type); + ERR("Unknown info type %u\n", info->type); return FALSE; } } @@ -1689,7 +1689,7 @@ BOOL WINAPI SetupCopyOEMInfA( SetLastError(ERROR_INVALID_PARAMETER); else if (!(SourceInfFileNameW = MultiByteToUnicode(SourceInfFileName, CP_ACP))) SetLastError(ERROR_INVALID_PARAMETER); - else if (!(OEMSourceMediaLocationW = MultiByteToUnicode(OEMSourceMediaLocation, CP_ACP))) + else if (OEMSourceMediaType != SPOST_NONE && !(OEMSourceMediaLocationW = MultiByteToUnicode(OEMSourceMediaLocation, CP_ACP))) SetLastError(ERROR_INVALID_PARAMETER); else { @@ -1743,6 +1743,29 @@ cleanup: return ret; } +static int compare_files( HANDLE file1, HANDLE file2 ) +{ + char buffer1[2048]; + char buffer2[2048]; + DWORD size1; + DWORD size2; + + while( ReadFile(file1, buffer1, sizeof(buffer1), &size1, NULL) && + ReadFile(file2, buffer2, sizeof(buffer2), &size2, NULL) ) + { + int ret; + if (size1 != size2) + return size1 > size2 ? 1 : -1; + if (!size1) + return 0; + ret = memcmp( buffer1, buffer2, size1 ); + if (ret) + return ret; + } + + return 0; +} + /*********************************************************************** * SetupCopyOEMInfW (SETUPAPI.@) */ @@ -1767,6 +1790,8 @@ BOOL WINAPI SetupCopyOEMInfW( SetLastError(ERROR_INVALID_PARAMETER); else if (OEMSourceMediaType != SPOST_NONE && OEMSourceMediaType != SPOST_PATH && OEMSourceMediaType != SPOST_URL) SetLastError(ERROR_INVALID_PARAMETER); + else if (OEMSourceMediaType != SPOST_NONE && !OEMSourceMediaLocation) + SetLastError(ERROR_INVALID_PARAMETER); else if (CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY)) { TRACE("Unknown flags: 0x%08lx\n", CopyStyle & ~(SP_COPY_DELETESOURCE | SP_COPY_REPLACEONLY | SP_COPY_NOOVERWRITE | SP_COPY_OEMINF_CATALOG_ONLY)); @@ -1776,7 +1801,7 @@ BOOL WINAPI SetupCopyOEMInfW( SetLastError(ERROR_INVALID_PARAMETER); else if (CopyStyle & SP_COPY_OEMINF_CATALOG_ONLY) { - FIXME("CopyStyle 0x%lx not supported\n", SP_COPY_OEMINF_CATALOG_ONLY); + FIXME("CopyStyle 0x%x not supported\n", SP_COPY_OEMINF_CATALOG_ONLY); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); } else @@ -1788,29 +1813,68 @@ BOOL WINAPI SetupCopyOEMInfW( SIZE_T len; LPWSTR pFullFileName = NULL; LPWSTR pFileName; /* Pointer into pFullFileName buffer */ + HANDLE hSourceFile = INVALID_HANDLE_VALUE; if (OEMSourceMediaType == SPOST_PATH || OEMSourceMediaType == SPOST_URL) FIXME("OEMSourceMediaType 0x%lx ignored\n", OEMSourceMediaType); - /* Search if the specified .inf file already exists in %WINDIR%\Inf */ - AlreadyExists = FALSE; /* FIXME */ - - if (!AlreadyExists && CopyStyle & SP_COPY_REPLACEONLY) + /* Check if source file exists, and open it */ + if (strchrW(SourceInfFileName, '\\' ) || strchrW(SourceInfFileName, '/' )) + { + WCHAR *path; + + if (!(len = GetFullPathNameW(SourceInfFileName, 0, NULL, NULL))) + return FALSE; + if (!(path = MyMalloc(len * sizeof(WCHAR)))) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + GetFullPathNameW(SourceInfFileName, len, path, NULL); + hSourceFile = CreateFileW( + path, FILE_READ_DATA | FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + MyFree(path); + } + else /* try Windows directory */ + { + WCHAR *path, *p; + static const WCHAR Inf[] = {'\\','i','n','f','\\',0}; + static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0}; + + len = GetWindowsDirectoryW(NULL, 0) + strlenW(SourceInfFileName) + 12; + if (!(path = MyMalloc(len * sizeof(WCHAR)))) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + GetWindowsDirectoryW(path, len); + p = path + strlenW(path); + strcpyW(p, Inf); + strcatW(p, SourceInfFileName); + hSourceFile = CreateFileW( + path, FILE_READ_DATA | FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + if (hSourceFile == INVALID_HANDLE_VALUE) + { + strcpyW(p, System32); + strcatW(p, SourceInfFileName); + hSourceFile = CreateFileW( + path, FILE_READ_DATA | FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + } + MyFree(path); + } + if (hSourceFile == INVALID_HANDLE_VALUE) { - /* FIXME: set DestinationInfFileName, RequiredSize, DestinationInfFileNameComponent */ SetLastError(ERROR_FILE_NOT_FOUND); goto cleanup; } - else if (AlreadyExists && (CopyStyle & SP_COPY_NOOVERWRITE)) - { - //SetLastError(ERROR_FILE_EXISTS); - /* FIXME: set return fields */ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - FIXME("File already exists. Need to return its name!\n"); - goto cleanup; - } - /* Search the number to give to OEM??.INF */ + /* Prepare .inf file specification */ len = MAX_PATH + 1 + strlenW(InfDirectory) + 13; pFullFileName = MyMalloc(len * sizeof(WCHAR)); if (!pFullFileName) @@ -1825,7 +1889,70 @@ BOOL WINAPI SetupCopyOEMInfW( strcatW(pFullFileName, BackSlash); strcatW(pFullFileName, InfDirectory); pFileName = &pFullFileName[strlenW(pFullFileName)]; - sprintfW(pFileName, OemFileMask, NextFreeNumber); + + /* Search if the specified .inf file already exists in %WINDIR%\Inf */ + AlreadyExists = FALSE; + strcpyW(pFileName, OemFileMask); + hSearch = FindFirstFileW(pFullFileName, &FindFileData); + if (hSearch != INVALID_HANDLE_VALUE) + { + LARGE_INTEGER SourceFileSize; + + if (GetFileSizeEx(hSourceFile, &SourceFileSize)) + { + do + { + LARGE_INTEGER DestFileSize; + HANDLE hDestFile; + + strcpyW(pFileName, FindFileData.cFileName); + hDestFile = CreateFileW( + pFullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + if (hDestFile != INVALID_HANDLE_VALUE) + { + if (GetFileSizeEx(hDestFile, &DestFileSize) + && DestFileSize.QuadPart == SourceFileSize.QuadPart + && compare_files(hSourceFile, hDestFile)) + { + TRACE("%s already exists as %s\n", + debugstr_w(SourceInfFileName), debugstr_w(pFileName)); + AlreadyExists = TRUE; + } + } + } while (!AlreadyExists && FindNextFileW(hSearch, &FindFileData)); + } + FindClose(hSearch); + hSearch = INVALID_HANDLE_VALUE; + } + + if (!AlreadyExists && CopyStyle & SP_COPY_REPLACEONLY) + { + /* FIXME: set DestinationInfFileName, RequiredSize, DestinationInfFileNameComponent */ + SetLastError(ERROR_FILE_NOT_FOUND); + goto cleanup; + } + else if (AlreadyExists && (CopyStyle & SP_COPY_NOOVERWRITE)) + { + DWORD Size = strlenW(pFileName) + 1; + + if (RequiredSize) + *RequiredSize = Size; + if (DestinationInfFileNameSize == 0) + SetLastError(ERROR_FILE_EXISTS); + else if (DestinationInfFileNameSize < Size) + SetLastError(ERROR_INSUFFICIENT_BUFFER); + else + { + SetLastError(ERROR_FILE_EXISTS); + strcpyW(DestinationInfFileName, pFileName); + } + goto cleanup; + } + + /* Search the number to give to OEM??.INF */ + strcpyW(pFileName, OemFileMask); hSearch = FindFirstFileW(pFullFileName, &FindFileData); if (hSearch == INVALID_HANDLE_VALUE) { @@ -1840,7 +1967,8 @@ BOOL WINAPI SetupCopyOEMInfW( if (swscanf(FindFileData.cFileName, OemFileSpecification, &CurrentNumber) == 1 && CurrentNumber <= 99999) { - NextFreeNumber = CurrentNumber + 1; + if (CurrentNumber >= NextFreeNumber) + NextFreeNumber = CurrentNumber + 1; } } while (FindNextFileW(hSearch, &FindFileData)); } @@ -1856,26 +1984,30 @@ BOOL WINAPI SetupCopyOEMInfW( sprintfW(pFileName, OemFileSpecification, NextFreeNumber); TRACE("Next available file is %s\n", debugstr_w(pFileName)); - if (RequiredSize) - *RequiredSize = len; - if (DestinationInfFileName) - { - if (DestinationInfFileNameSize < len) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - goto cleanup; - } - strcpyW(DestinationInfFileName, pFullFileName); - if (DestinationInfFileNameComponent) - *DestinationInfFileNameComponent = &DestinationInfFileName[pFileName - pFullFileName]; - } - if (!CopyFileW(SourceInfFileName, pFullFileName, TRUE)) { TRACE("CopyFileW() failed with error 0x%lx\n", GetLastError()); goto cleanup; } + len = strlenW(pFullFileName) + 1; + if (RequiredSize) + *RequiredSize = len; + if (DestinationInfFileName) + { + if (DestinationInfFileNameSize >= len) + { + strcpyW(DestinationInfFileName, pFullFileName); + if (DestinationInfFileNameComponent) + *DestinationInfFileNameComponent = &DestinationInfFileName[pFileName - pFullFileName]; + } + else + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + goto cleanup; + } + } + if (CopyStyle & SP_COPY_DELETESOURCE) { if (!DeleteFileW(SourceInfFileName)) @@ -1888,6 +2020,8 @@ BOOL WINAPI SetupCopyOEMInfW( ret = TRUE; cleanup: + if (hSourceFile != INVALID_HANDLE_VALUE) + CloseHandle(hSourceFile); if (hSearch != INVALID_HANDLE_VALUE) FindClose(hSearch); MyFree(pFullFileName); diff --git a/reactos/dll/win32/setupapi/misc.c b/reactos/dll/win32/setupapi/misc.c index 7a4c6e68453..40e0f473394 100644 --- a/reactos/dll/win32/setupapi/misc.c +++ b/reactos/dll/win32/setupapi/misc.c @@ -2,6 +2,7 @@ * Setupapi miscellaneous functions * * Copyright 2005 Eric Kohl + * Copyright 2007 Hans Leidekker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1221,3 +1222,437 @@ GetVersionInfoFromImage(LPWSTR lpFileName, return TRUE; } + +/*********************************************************************** + * InstallCatalog (SETUPAPI.@) + */ +DWORD WINAPI InstallCatalog( LPCSTR catalog, LPCSTR basename, LPSTR fullname ) +{ + FIXME("%s, %s, %p\n", debugstr_a(catalog), debugstr_a(basename), fullname); + return 0; +} + +static UINT detect_compression_type( LPCWSTR file ) +{ + DWORD size; + HANDLE handle; + UINT type = FILE_COMPRESSION_NONE; + static const BYTE LZ_MAGIC[] = { 0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33 }; + static const BYTE MSZIP_MAGIC[] = { 0x4b, 0x57, 0x41, 0x4a }; + static const BYTE NTCAB_MAGIC[] = { 0x4d, 0x53, 0x43, 0x46 }; + BYTE buffer[8]; + + handle = CreateFileW( file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); + if (handle == INVALID_HANDLE_VALUE) + { + ERR("cannot open file %s\n", debugstr_w(file)); + return FILE_COMPRESSION_NONE; + } + if (!ReadFile( handle, buffer, sizeof(buffer), &size, NULL ) || size != sizeof(buffer)) + { + CloseHandle( handle ); + return FILE_COMPRESSION_NONE; + } + if (!memcmp( buffer, LZ_MAGIC, sizeof(LZ_MAGIC) )) type = FILE_COMPRESSION_WINLZA; + else if (!memcmp( buffer, MSZIP_MAGIC, sizeof(MSZIP_MAGIC) )) type = FILE_COMPRESSION_MSZIP; + else if (!memcmp( buffer, NTCAB_MAGIC, sizeof(NTCAB_MAGIC) )) type = FILE_COMPRESSION_MSZIP; /* not a typo */ + + CloseHandle( handle ); + return type; +} + +static BOOL get_file_size( LPCWSTR file, DWORD *size ) +{ + HANDLE handle; + + handle = CreateFileW( file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); + if (handle == INVALID_HANDLE_VALUE) + { + ERR("cannot open file %s\n", debugstr_w(file)); + return FALSE; + } + *size = GetFileSize( handle, NULL ); + CloseHandle( handle ); + return TRUE; +} + +static BOOL get_file_sizes_none( LPCWSTR source, DWORD *source_size, DWORD *target_size ) +{ + DWORD size; + + if (!get_file_size( source, &size )) return FALSE; + if (source_size) *source_size = size; + if (target_size) *target_size = size; + return TRUE; +} + +static BOOL get_file_sizes_lz( LPCWSTR source, DWORD *source_size, DWORD *target_size ) +{ + DWORD size; + BOOL ret = TRUE; + + if (source_size) + { + if (!get_file_size( source, &size )) ret = FALSE; + else *source_size = size; + } + if (target_size) + { + INT file; + OFSTRUCT of; + + if ((file = LZOpenFileW( (LPWSTR)source, &of, OF_READ )) < 0) + { + ERR("cannot open source file for reading\n"); + return FALSE; + } + *target_size = LZSeek( file, 0, 2 ); + LZClose( file ); + } + return ret; +} + +static UINT CALLBACK file_compression_info_callback( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 ) +{ + DWORD *size = context; + FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)param1; + + switch (notification) + { + case SPFILENOTIFY_FILEINCABINET: + { + *size = info->FileSize; + return FILEOP_SKIP; + } + default: return NO_ERROR; + } +} + +static BOOL get_file_sizes_cab( LPCWSTR source, DWORD *source_size, DWORD *target_size ) +{ + DWORD size; + BOOL ret = TRUE; + + if (source_size) + { + if (!get_file_size( source, &size )) ret = FALSE; + else *source_size = size; + } + if (target_size) + { + ret = SetupIterateCabinetW( source, 0, file_compression_info_callback, target_size ); + } + return ret; +} + +/*********************************************************************** + * SetupGetFileCompressionInfoExA (SETUPAPI.@) + * + * See SetupGetFileCompressionInfoExW. + */ +BOOL WINAPI SetupGetFileCompressionInfoExA( PCSTR source, PSTR name, DWORD len, PDWORD required, + PDWORD source_size, PDWORD target_size, PUINT type ) +{ + BOOL ret; + WCHAR *nameW = NULL, *sourceW = NULL; + DWORD nb_chars = 0; + LPSTR nameA; + + TRACE("%s, %p, %lu, %p, %p, %p, %p\n", debugstr_a(source), name, len, required, + source_size, target_size, type); + + if (!source || !(sourceW = MultiByteToUnicode( source, CP_ACP ))) return FALSE; + + if (name) + { + ret = SetupGetFileCompressionInfoExW( sourceW, NULL, 0, &nb_chars, NULL, NULL, NULL ); + if (!(nameW = HeapAlloc( GetProcessHeap(), 0, nb_chars * sizeof(WCHAR) ))) + { + MyFree( sourceW ); + return FALSE; + } + } + ret = SetupGetFileCompressionInfoExW( sourceW, nameW, nb_chars, &nb_chars, source_size, target_size, type ); + if (ret) + { + if ((nameA = UnicodeToMultiByte( nameW, CP_ACP ))) + { + if (name && len >= nb_chars) lstrcpyA( name, nameA ); + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + ret = FALSE; + } + MyFree( nameA ); + } + } + if (required) *required = nb_chars; + HeapFree( GetProcessHeap(), 0, nameW ); + MyFree( sourceW ); + + return ret; +} + +/*********************************************************************** + * SetupGetFileCompressionInfoExW (SETUPAPI.@) + * + * Get compression type and compressed/uncompressed sizes of a given file. + * + * PARAMS + * source [I] File to examine. + * name [O] Actual filename used. + * len [I] Length in characters of 'name' buffer. + * required [O] Number of characters written to 'name'. + * source_size [O] Size of compressed file. + * target_size [O] Size of uncompressed file. + * type [O] Compression type. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI SetupGetFileCompressionInfoExW( PCWSTR source, PWSTR name, DWORD len, PDWORD required, + PDWORD source_size, PDWORD target_size, PUINT type ) +{ + UINT comp; + BOOL ret = FALSE; + DWORD source_len; + + TRACE("%s, %p, %lu, %p, %p, %p, %p\n", debugstr_w(source), name, len, required, + source_size, target_size, type); + + if (!source) return FALSE; + + source_len = lstrlenW( source ) + 1; + if (required) *required = source_len; + if (name && len >= source_len) + { + lstrcpyW( name, source ); + ret = TRUE; + } + else return FALSE; + + comp = detect_compression_type( source ); + if (type) *type = comp; + + switch (comp) + { + case FILE_COMPRESSION_MSZIP: + case FILE_COMPRESSION_NTCAB: ret = get_file_sizes_cab( source, source_size, target_size ); break; + case FILE_COMPRESSION_NONE: ret = get_file_sizes_none( source, source_size, target_size ); break; + case FILE_COMPRESSION_WINLZA: ret = get_file_sizes_lz( source, source_size, target_size ); break; + default: break; + } + return ret; +} + +/*********************************************************************** + * SetupGetFileCompressionInfoA (SETUPAPI.@) + * + * See SetupGetFileCompressionInfoW. + */ +DWORD WINAPI SetupGetFileCompressionInfoA( PCSTR source, PSTR *name, PDWORD source_size, + PDWORD target_size, PUINT type ) +{ + BOOL ret; + DWORD error, required; + LPSTR actual_name; + + TRACE("%s, %p, %p, %p, %p\n", debugstr_a(source), name, source_size, target_size, type); + + if (!source || !name || !source_size || !target_size || !type) + return ERROR_INVALID_PARAMETER; + + ret = SetupGetFileCompressionInfoExA( source, NULL, 0, &required, NULL, NULL, NULL ); + if (!(actual_name = MyMalloc( required ))) return ERROR_NOT_ENOUGH_MEMORY; + + ret = SetupGetFileCompressionInfoExA( source, actual_name, required, &required, + source_size, target_size, type ); + if (!ret) + { + error = GetLastError(); + MyFree( actual_name ); + return error; + } + *name = actual_name; + return ERROR_SUCCESS; +} + +/*********************************************************************** + * SetupGetFileCompressionInfoW (SETUPAPI.@) + * + * Get compression type and compressed/uncompressed sizes of a given file. + * + * PARAMS + * source [I] File to examine. + * name [O] Actual filename used. + * source_size [O] Size of compressed file. + * target_size [O] Size of uncompressed file. + * type [O] Compression type. + * + * RETURNS + * Success: ERROR_SUCCESS + * Failure: Win32 error code. + */ +DWORD WINAPI SetupGetFileCompressionInfoW( PCWSTR source, PWSTR *name, PDWORD source_size, + PDWORD target_size, PUINT type ) +{ + BOOL ret; + DWORD error, required; + LPWSTR actual_name; + + TRACE("%s, %p, %p, %p, %p\n", debugstr_w(source), name, source_size, target_size, type); + + if (!source || !name || !source_size || !target_size || !type) + return ERROR_INVALID_PARAMETER; + + ret = SetupGetFileCompressionInfoExW( source, NULL, 0, &required, NULL, NULL, NULL ); + if (!(actual_name = MyMalloc( required ))) return ERROR_NOT_ENOUGH_MEMORY; + + ret = SetupGetFileCompressionInfoExW( source, actual_name, required, &required, + source_size, target_size, type ); + if (!ret) + { + error = GetLastError(); + MyFree( actual_name ); + return error; + } + *name = actual_name; + return ERROR_SUCCESS; +} + +static DWORD decompress_file_lz( LPCWSTR source, LPCWSTR target ) +{ + DWORD ret; + LONG error; + INT src, dst; + OFSTRUCT sof, dof; + + if ((src = LZOpenFileW( (LPWSTR)source, &sof, OF_READ )) < 0) + { + ERR("cannot open source file for reading\n"); + return ERROR_FILE_NOT_FOUND; + } + if ((dst = LZOpenFileW( (LPWSTR)target, &dof, OF_CREATE )) < 0) + { + ERR("cannot open target file for writing\n"); + LZClose( src ); + return ERROR_FILE_NOT_FOUND; + } + if ((error = LZCopy( src, dst )) >= 0) ret = ERROR_SUCCESS; + else + { + WARN("failed to decompress file %ld\n", error); + ret = ERROR_INVALID_DATA; + } + + LZClose( src ); + LZClose( dst ); + return ret; +} + +static UINT CALLBACK decompress_or_copy_callback( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 ) +{ + FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)param1; + + switch (notification) + { + case SPFILENOTIFY_FILEINCABINET: + { + LPCWSTR filename, targetname = context; + WCHAR *p; + + if ((p = strrchrW( targetname, '\\' ))) filename = p + 1; + else filename = targetname; + + if (!lstrcmpiW( filename, info->NameInCabinet )) + { + strcpyW( info->FullTargetName, targetname ); + return FILEOP_DOIT; + } + return FILEOP_SKIP; + } + default: return NO_ERROR; + } +} + +static DWORD decompress_file_cab( LPCWSTR source, LPCWSTR target ) +{ + BOOL ret; + + ret = SetupIterateCabinetW( source, 0, decompress_or_copy_callback, (PVOID)target ); + + if (ret) return ERROR_SUCCESS; + else return GetLastError(); +} + +/*********************************************************************** + * SetupDecompressOrCopyFileA (SETUPAPI.@) + * + * See SetupDecompressOrCopyFileW. + */ +DWORD WINAPI SetupDecompressOrCopyFileA( PCSTR source, PCSTR target, PUINT type ) +{ + DWORD ret = FALSE; + WCHAR *sourceW = NULL, *targetW = NULL; + + if (source && !(sourceW = MultiByteToUnicode( source, CP_ACP ))) return FALSE; + if (target && !(targetW = MultiByteToUnicode( target, CP_ACP ))) + { + MyFree( sourceW ); + return ERROR_NOT_ENOUGH_MEMORY; + } + + ret = SetupDecompressOrCopyFileW( sourceW, targetW, type ); + + MyFree( sourceW ); + MyFree( targetW ); + + return ret; +} + +/*********************************************************************** + * SetupDecompressOrCopyFileW (SETUPAPI.@) + * + * Copy a file and decompress it if needed. + * + * PARAMS + * source [I] File to copy. + * target [I] Filename of the copy. + * type [I] Compression type. + * + * RETURNS + * Success: ERROR_SUCCESS + * Failure: Win32 error code. + */ +DWORD WINAPI SetupDecompressOrCopyFileW( PCWSTR source, PCWSTR target, PUINT type ) +{ + UINT comp; + DWORD ret = ERROR_INVALID_PARAMETER; + + if (!source || !target) return ERROR_INVALID_PARAMETER; + + if (!type) comp = detect_compression_type( source ); + else comp = *type; + + switch (comp) + { + case FILE_COMPRESSION_NONE: + if (CopyFileW( source, target, FALSE )) ret = ERROR_SUCCESS; + else ret = GetLastError(); + break; + case FILE_COMPRESSION_WINLZA: + ret = decompress_file_lz( source, target ); + break; + case FILE_COMPRESSION_NTCAB: + case FILE_COMPRESSION_MSZIP: + ret = decompress_file_cab( source, target ); + break; + default: + WARN("unknown compression type %d\n", comp); + break; + } + + TRACE("%s -> %s %d\n", debugstr_w(source), debugstr_w(target), comp); + return ret; +} diff --git a/reactos/dll/win32/setupapi/parser.c b/reactos/dll/win32/setupapi/parser.c index b4b3f104a61..957c0aac5e5 100644 --- a/reactos/dll/win32/setupapi/parser.c +++ b/reactos/dll/win32/setupapi/parser.c @@ -944,10 +944,21 @@ static struct inf_file *parse_file( HANDLE handle, UINT *error_line, DWORD style if (!RtlIsTextUnicode( buffer, size, NULL )) { - WCHAR *new_buff = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ); - if (new_buff) + static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf }; + WCHAR *new_buff; + UINT codepage = CP_ACP; + UINT offset = 0; + + if (size > sizeof(utf8_bom) && !memcmp( buffer, utf8_bom, sizeof(utf8_bom) )) { - DWORD len = MultiByteToWideChar( CP_ACP, 0, buffer, size, new_buff, size ); + codepage = CP_UTF8; + offset = sizeof(utf8_bom); + } + + if ((new_buff = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) + { + DWORD len = MultiByteToWideChar( codepage, 0, (char *)buffer + offset, + size - offset, new_buff, size ); err = parse_buffer( file, new_buff, new_buff + len, error_line ); HeapFree( GetProcessHeap(), 0, new_buff ); } @@ -964,8 +975,6 @@ static struct inf_file *parse_file( HANDLE handle, UINT *error_line, DWORD style if (!err) /* now check signature */ { int version_index = find_section( file, Version ); - if (version_index == -1 && (style & INF_STYLE_OLDNT)) - goto done; if (version_index != -1) { struct line *line = find_line( file, version_index, Signature ); @@ -978,7 +987,7 @@ static struct inf_file *parse_file( HANDLE handle, UINT *error_line, DWORD style } } if (error_line) *error_line = 0; - err = ERROR_WRONG_INF_STYLE; + if (style & INF_STYLE_WIN4) err = ERROR_WRONG_INF_STYLE; } done: @@ -1215,7 +1224,7 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err /* Not enough memory */ SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetupCloseInfFile((HINF)file); - return NULL; + return (HINF)INVALID_HANDLE_VALUE; } else if (!PARSER_GetInfClassW((HINF)file, &ClassGuid, ClassName, strlenW(class) + 1, NULL)) { @@ -1223,7 +1232,7 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err HeapFree(GetProcessHeap(), 0, ClassName); SetLastError(ERROR_CLASS_MISMATCH); SetupCloseInfFile((HINF)file); - return NULL; + return (HINF)INVALID_HANDLE_VALUE; } else if (strcmpW(class, ClassName) != 0) { @@ -1231,7 +1240,7 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err HeapFree(GetProcessHeap(), 0, ClassName); SetLastError(ERROR_CLASS_MISMATCH); SetupCloseInfFile((HINF)file); - return NULL; + return (HINF)INVALID_HANDLE_VALUE; } HeapFree(GetProcessHeap(), 0, ClassName); } @@ -1312,9 +1321,10 @@ void WINAPI SetupCloseInfFile( HINF hinf ) struct inf_file *file = hinf; unsigned int i; - if (file != NULL) + if (file != NULL && file != INVALID_HANDLE_VALUE) { - for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] ); + for (i = 0; i < file->nb_sections; i++) + HeapFree( GetProcessHeap(), 0, file->sections[i] ); HeapFree( GetProcessHeap(), 0, file->filename ); HeapFree( GetProcessHeap(), 0, file->sections ); HeapFree( GetProcessHeap(), 0, file->fields ); diff --git a/reactos/dll/win32/setupapi/query.c b/reactos/dll/win32/setupapi/query.c index 5df1157ee49..90820710e91 100644 --- a/reactos/dll/win32/setupapi/query.c +++ b/reactos/dll/win32/setupapi/query.c @@ -22,6 +22,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(setupapi); +static const WCHAR source_disks_names[] = + {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0}; +static const WCHAR source_disks_files[] = + {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0}; + /* fills the PSP_INF_INFORMATION struct fill_info is TRUE * always returns the required size of the information */ @@ -270,3 +275,414 @@ BOOL WINAPI SetupQueryInfFileInformationW(PSP_INF_INFORMATION InfInformation, lstrcpyW(ReturnBuffer, ptr); return TRUE; } + +/*********************************************************************** + * SetupGetSourceFileLocationA (SETUPAPI.@) + */ + +BOOL WINAPI SetupGetSourceFileLocationA( HINF hinf, PINFCONTEXT context, PCSTR filename, + PUINT source_id, PSTR buffer, DWORD buffer_size, + PDWORD required_size ) +{ + BOOL ret = FALSE; + WCHAR *filenameW = NULL, *bufferW = NULL; + DWORD required; + INT size; + + TRACE("%p, %p, %s, %p, %p, 0x%08lx, %p\n", hinf, context, debugstr_a(filename), source_id, + buffer, buffer_size, required_size); + + if (filename && *filename && !(filenameW = strdupAtoW( filename ))) + return FALSE; + + if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, NULL, 0, &required )) + goto done; + + if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) ))) + goto done; + + if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, bufferW, required, NULL )) + goto done; + + size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); + if (required_size) *required_size = size; + + if (buffer) + { + if (buffer_size >= size) + WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL ); + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + goto done; + } + } + ret = TRUE; + + done: + HeapFree( GetProcessHeap(), 0, filenameW ); + HeapFree( GetProcessHeap(), 0, bufferW ); + return ret; +} + +static LPWSTR get_source_id( HINF hinf, PINFCONTEXT context, PCWSTR filename ) +{ + WCHAR Section[MAX_PATH]; + DWORD size; + LPWSTR source_id; + BOOL ret; + + ret = SetupDiGetActualSectionToInstallW(hinf, source_disks_files, Section, MAX_PATH, NULL, NULL); + if (!ret) + return NULL; + + if (!SetupFindFirstLineW( hinf, Section, filename, context ) && + !SetupFindFirstLineW( hinf, source_disks_files, filename, context )) + return NULL; + + if (!SetupGetStringFieldW( context, 1, NULL, 0, &size )) + return NULL; + + if (!(source_id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) + return NULL; + + if (!SetupGetStringFieldW( context, 1, source_id, size, NULL )) + { + HeapFree( GetProcessHeap(), 0, source_id ); + return NULL; + } + + ret = SetupDiGetActualSectionToInstallW(hinf, source_disks_names, Section, MAX_PATH, NULL, NULL); + if (!ret) + return NULL; + + if (!SetupFindFirstLineW( hinf, Section, source_id, context ) && + !SetupFindFirstLineW( hinf, source_disks_names, source_id, context )) + { + HeapFree( GetProcessHeap(), 0, source_id ); + return NULL; + } + return source_id; +} + +/*********************************************************************** + * SetupGetSourceFileLocationW (SETUPAPI.@) + */ + +BOOL WINAPI SetupGetSourceFileLocationW( HINF hinf, PINFCONTEXT context, PCWSTR filename, + PUINT source_id, PWSTR buffer, DWORD buffer_size, + PDWORD required_size ) +{ + INFCONTEXT ctx; + WCHAR *end, *source_id_str; + + TRACE("%p, %p, %s, %p, %p, 0x%08lx, %p\n", hinf, context, debugstr_w(filename), source_id, + buffer, buffer_size, required_size); + + if (!context) context = &ctx; + + if (!(source_id_str = get_source_id( hinf, context, filename ))) + return FALSE; + + *source_id = strtolW( source_id_str, &end, 10 ); + if (end == source_id_str || *end) + { + HeapFree( GetProcessHeap(), 0, source_id_str ); + return FALSE; + } + HeapFree( GetProcessHeap(), 0, source_id_str ); + + if (SetupGetStringFieldW( context, 4, buffer, buffer_size, required_size )) + return TRUE; + + if (required_size) *required_size = 1; + if (buffer) + { + if (buffer_size >= 1) buffer[0] = 0; + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return FALSE; + } + } + return TRUE; +} + +/*********************************************************************** + * SetupGetSourceInfoA (SETUPAPI.@) + */ + +BOOL WINAPI SetupGetSourceInfoA( HINF hinf, UINT source_id, UINT info, + PSTR buffer, DWORD buffer_size, LPDWORD required_size ) +{ + BOOL ret = FALSE; + WCHAR *bufferW = NULL; + DWORD required; + INT size; + + TRACE("%p, %d, %d, %p, %lu, %p\n", hinf, source_id, info, buffer, buffer_size, + required_size); + + if (!SetupGetSourceInfoW( hinf, source_id, info, NULL, 0, &required )) + return FALSE; + + if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) ))) + return FALSE; + + if (!SetupGetSourceInfoW( hinf, source_id, info, bufferW, required, NULL )) + goto done; + + size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); + if (required_size) *required_size = size; + + if (buffer) + { + if (buffer_size >= size) + WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL ); + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + goto done; + } + } + ret = TRUE; + + done: + HeapFree( GetProcessHeap(), 0, bufferW ); + return ret; +} + +/*********************************************************************** + * SetupGetSourceInfoW (SETUPAPI.@) + */ + +BOOL WINAPI SetupGetSourceInfoW( HINF hinf, UINT source_id, UINT info, + PWSTR buffer, DWORD buffer_size, LPDWORD required_size ) +{ + WCHAR Section[MAX_PATH]; + INFCONTEXT ctx; + WCHAR source_id_str[11]; + static const WCHAR fmt[] = {'%','d',0}; + DWORD index; + BOOL ret; + + TRACE("%p, %d, %d, %p, %lu, %p\n", hinf, source_id, info, buffer, buffer_size, + required_size); + + sprintfW( source_id_str, fmt, source_id ); + + ret = SetupDiGetActualSectionToInstallW(hinf, source_disks_names, Section, MAX_PATH, NULL, NULL); + if (!ret) + return FALSE; + + if (!SetupFindFirstLineW( hinf, Section, source_id_str, &ctx ) && + !SetupFindFirstLineW( hinf, source_disks_names, source_id_str, &ctx )) + return FALSE; + + switch (info) + { + case SRCINFO_PATH: index = 4; break; + case SRCINFO_TAGFILE: index = 2; break; + case SRCINFO_DESCRIPTION: index = 1; break; + default: + WARN("unknown info level: %d\n", info); + return FALSE; + } + + if (SetupGetStringFieldW( &ctx, index, buffer, buffer_size, required_size )) + return TRUE; + + if (required_size) *required_size = 1; + if (buffer) + { + if (buffer_size >= 1) buffer[0] = 0; + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return FALSE; + } + } + return TRUE; +} + +/*********************************************************************** + * SetupGetTargetPathA (SETUPAPI.@) + */ + +BOOL WINAPI SetupGetTargetPathA( HINF hinf, PINFCONTEXT context, PCSTR section, PSTR buffer, + DWORD buffer_size, PDWORD required_size ) +{ + BOOL ret = FALSE; + WCHAR *sectionW = NULL, *bufferW = NULL; + DWORD required; + INT size; + + TRACE("%p, %p, %s, %p, 0x%08lx, %p\n", hinf, context, debugstr_a(section), buffer, + buffer_size, required_size); + + if (section && !(sectionW = strdupAtoW( section ))) + return FALSE; + + if (!SetupGetTargetPathW( hinf, context, sectionW, NULL, 0, &required )) + goto done; + + if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) ))) + goto done; + + if (!SetupGetTargetPathW( hinf, context, sectionW, bufferW, required, NULL )) + goto done; + + size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); + if (required_size) *required_size = size; + + if (buffer) + { + if (buffer_size >= size) + WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL ); + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + goto done; + } + } + ret = TRUE; + + done: + HeapFree( GetProcessHeap(), 0, sectionW ); + HeapFree( GetProcessHeap(), 0, bufferW ); + return ret; +} + +/*********************************************************************** + * SetupGetTargetPathW (SETUPAPI.@) + */ + +BOOL WINAPI SetupGetTargetPathW( HINF hinf, PINFCONTEXT context, PCWSTR section, PWSTR buffer, + DWORD buffer_size, PDWORD required_size ) +{ + static const WCHAR destination_dirs[] = + {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0}; + static const WCHAR default_dest_dir[] = + {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0}; + + INFCONTEXT ctx; + WCHAR *dir; + INT size; + + TRACE("%p, %p, %s, %p, 0x%08lx, %p\n", hinf, context, debugstr_w(section), buffer, + buffer_size, required_size); + + if (context && !SetupFindFirstLineW( hinf, destination_dirs, NULL, context )) return FALSE; + else if (section && !SetupFindFirstLineW( hinf, section, NULL, &ctx )) return FALSE; + else if (!SetupFindFirstLineW( hinf, destination_dirs, default_dest_dir, &ctx )) return FALSE; + + if (!(dir = PARSER_get_dest_dir( context ? context : &ctx ))) return FALSE; + + size = lstrlenW( dir ) + 1; + if (required_size) *required_size = size; + + if (buffer) + { + if (buffer_size >= size) + lstrcpyW( buffer, dir ); + else + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + HeapFree( GetProcessHeap(), 0, dir ); + return FALSE; + } + } + HeapFree( GetProcessHeap(), 0, dir ); + return TRUE; +} + +/*********************************************************************** + * SetupQueryInfOriginalFileInformationA (SETUPAPI.@) + */ +BOOL WINAPI SetupQueryInfOriginalFileInformationA( + PSP_INF_INFORMATION InfInformation, UINT InfIndex, + PSP_ALTPLATFORM_INFO AlternativePlatformInfo, + PSP_ORIGINAL_FILE_INFO_A OriginalFileInfo) +{ + BOOL ret; + SP_ORIGINAL_FILE_INFO_W OriginalFileInfoW; + + TRACE("(%p, %d, %p, %p)\n", InfInformation, InfIndex, + AlternativePlatformInfo, OriginalFileInfo); + + if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo)) + { + ERR("incorrect OriginalFileInfo->cbSize of %lu\n", OriginalFileInfo->cbSize); + SetLastError( ERROR_INVALID_USER_BUFFER ); + return FALSE; + } + + OriginalFileInfoW.cbSize = sizeof(OriginalFileInfoW); + ret = SetupQueryInfOriginalFileInformationW(InfInformation, InfIndex, + AlternativePlatformInfo, &OriginalFileInfoW); + if (ret) + { + WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalInfName, MAX_PATH, + OriginalFileInfo->OriginalInfName, MAX_PATH, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalCatalogName, MAX_PATH, + OriginalFileInfo->OriginalCatalogName, MAX_PATH, NULL, NULL); + } + + return ret; +} + +/*********************************************************************** + * SetupQueryInfOriginalFileInformationW (SETUPAPI.@) + */ +BOOL WINAPI SetupQueryInfOriginalFileInformationW( + PSP_INF_INFORMATION InfInformation, UINT InfIndex, + PSP_ALTPLATFORM_INFO AlternativePlatformInfo, + PSP_ORIGINAL_FILE_INFO_W OriginalFileInfo) +{ + LPCWSTR inf_name; + LPCWSTR inf_path; + HINF hinf; + static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 }; + static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 }; + + //SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + //return FALSE; + + FIXME("(%p, %d, %p, %p): semi-stub\n", InfInformation, InfIndex, + AlternativePlatformInfo, OriginalFileInfo); + + if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo)) + { + ERR("incorrect OriginalFileInfo->cbSize of %lu\n", OriginalFileInfo->cbSize); + return ERROR_INVALID_USER_BUFFER; + } + + inf_path = (LPWSTR)&InfInformation->VersionData[0]; + + /* FIXME: we should get OriginalCatalogName from CatalogFile line in + * the original inf file and cache it, but that would require building a + * .pnf file. */ + hinf = SetupOpenInfFileW(inf_path, NULL, INF_STYLE_WIN4, NULL); + if (hinf == INVALID_HANDLE_VALUE) return FALSE; + + if (!SetupGetLineTextW(NULL, hinf, wszVersion, wszCatalogFile, + OriginalFileInfo->OriginalCatalogName, + sizeof(OriginalFileInfo->OriginalCatalogName)/sizeof(OriginalFileInfo->OriginalCatalogName[0]), + NULL)) + { + OriginalFileInfo->OriginalCatalogName[0] = '\0'; + } + SetupCloseInfFile(hinf); + + /* FIXME: not quite correct as we just return the same file name as + * destination (copied) inf file, not the source (original) inf file. + * to fix it properly would require building a .pnf file */ + /* file name is stored in VersionData field of InfInformation */ + inf_name = strrchrW(inf_path, '\\'); + if (inf_name) inf_name++; + else inf_name = inf_path; + + strcpyW(OriginalFileInfo->OriginalInfName, inf_name); + + return TRUE; +} diff --git a/reactos/dll/win32/setupapi/queue.c b/reactos/dll/win32/setupapi/queue.c index b2830406473..60d8d5ac00c 100644 --- a/reactos/dll/win32/setupapi/queue.c +++ b/reactos/dll/win32/setupapi/queue.c @@ -74,19 +74,6 @@ inline static WCHAR *strdupW( const WCHAR *str ) return ret; } - -inline static WCHAR *strdupAtoW( const char *str ) -{ - WCHAR *ret = NULL; - if (str) - { - DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); - if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) - MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len ); - } - return ret; -} - inline static char *strdupWtoA( const WCHAR *str ) { char *ret = NULL; diff --git a/reactos/dll/win32/setupapi/setupapi.rbuild b/reactos/dll/win32/setupapi/setupapi.rbuild index 40c88d61eb6..ac05b30d6d2 100644 --- a/reactos/dll/win32/setupapi/setupapi.rbuild +++ b/reactos/dll/win32/setupapi/setupapi.rbuild @@ -1,4 +1,4 @@ - + . include/reactos/wine diff --git a/reactos/dll/win32/setupapi/setupapi.spec b/reactos/dll/win32/setupapi/setupapi.spec index a80fc0afbb1..d02ce8ac8f0 100644 --- a/reactos/dll/win32/setupapi/setupapi.spec +++ b/reactos/dll/win32/setupapi/setupapi.spec @@ -210,7 +210,7 @@ @ stdcall GetSetFileTimestamp(wstr ptr ptr ptr long) @ stdcall GetVersionInfoFromImage(wstr ptr ptr) @ stub InfIsFromOemLocation -@ stub InstallCatalog +@ stdcall InstallCatalog(str str ptr) @ stdcall InstallHinfSection(long long str long) InstallHinfSectionA @ stdcall InstallHinfSectionA(long long str long) @ stdcall InstallHinfSectionW(long long wstr long) @@ -230,7 +230,8 @@ @ stub QueryMultiSzValueToArray @ stdcall QueryRegistryValue(long wstr ptr ptr ptr) @ stub ReadAsciiOrUnicodeTextFile -@ stub RegistryDelnode +@ stdcall RegistryDelnode(long long) +# Yes, Microsoft really misspelled this one! @ stdcall RetreiveFileSecurity(wstr ptr) @ stub RetrieveServiceConfig @ stub SearchForInfFile @@ -257,8 +258,8 @@ @ stdcall SetupCopyOEMInfW(wstr wstr long long ptr long ptr ptr) @ stdcall SetupCreateDiskSpaceListA(ptr long long) @ stdcall SetupCreateDiskSpaceListW(ptr long long) -@ stub SetupDecompressOrCopyFileA -@ stub SetupDecompressOrCopyFileW +@ stdcall SetupDecompressOrCopyFileA(str str ptr) +@ stdcall SetupDecompressOrCopyFileW(wstr wstr ptr) @ stub SetupDefaultQueueCallback @ stdcall SetupDefaultQueueCallbackA(ptr long long long) @ stdcall SetupDefaultQueueCallbackW(ptr long long long) @@ -399,8 +400,10 @@ @ stub SetupGetBackupInformationW @ stdcall SetupGetBinaryField(ptr long ptr long ptr) @ stdcall SetupGetFieldCount(ptr) -@ stub SetupGetFileCompressionInfoA -@ stub SetupGetFileCompressionInfoW +@ stdcall SetupGetFileCompressionInfoA(str ptr ptr ptr ptr) +@ stdcall SetupGetFileCompressionInfoExA(str ptr long ptr ptr ptr ptr) +@ stdcall SetupGetFileCompressionInfoExW(wstr ptr long ptr ptr ptr ptr) +@ stdcall SetupGetFileCompressionInfoW(wstr ptr ptr ptr ptr) @ stdcall SetupGetFileQueueCount(long long ptr) @ stdcall SetupGetFileQueueFlags(long ptr) @ stdcall SetupGetInfFileListA(str long str long ptr) @@ -417,16 +420,16 @@ @ stdcall SetupGetLineTextW(ptr long wstr wstr ptr long ptr) @ stdcall SetupGetMultiSzFieldA(ptr long ptr long ptr) @ stdcall SetupGetMultiSzFieldW(ptr long ptr long ptr) -@ stub SetupGetSourceFileLocationA -@ stub SetupGetSourceFileLocationW +@ stdcall SetupGetSourceFileLocationA(ptr ptr str ptr ptr long ptr) +@ stdcall SetupGetSourceFileLocationW(ptr ptr wstr ptr ptr long ptr) @ stub SetupGetSourceFileSizeA @ stub SetupGetSourceFileSizeW -@ stub SetupGetSourceInfoA -@ stub SetupGetSourceInfoW +@ stdcall SetupGetSourceInfoA(ptr long long ptr long ptr) +@ stdcall SetupGetSourceInfoW(ptr long long ptr long ptr) @ stdcall SetupGetStringFieldA(ptr long ptr long ptr) @ stdcall SetupGetStringFieldW(ptr long ptr long ptr) -@ stub SetupGetTargetPathA -@ stub SetupGetTargetPathW +@ stdcall SetupGetTargetPathA(ptr ptr str ptr long ptr) +@ stdcall SetupGetTargetPathW(ptr ptr wstr ptr long ptr) @ stdcall SetupInitDefaultQueueCallback(long) @ stdcall SetupInitDefaultQueueCallbackEx(long long long long ptr) @ stdcall SetupInitializeFileLogA(str long) @@ -465,8 +468,8 @@ @ stub SetupQueryFileLogW @ stdcall SetupQueryInfFileInformationA(ptr long str long ptr) @ stdcall SetupQueryInfFileInformationW(ptr long wstr long ptr) -@ stub SetupQueryInfOriginalFileInformationA -@ stub SetupQueryInfOriginalFileInformationW +@ stdcall SetupQueryInfOriginalFileInformationA(ptr long ptr ptr) +@ stdcall SetupQueryInfOriginalFileInformationW(ptr long ptr ptr) @ stub SetupQueryInfVersionInformationA @ stub SetupQueryInfVersionInformationW @ stub SetupQuerySourceListA @@ -513,8 +516,8 @@ @ stdcall SetupSetFileQueueFlags(long long long) @ stub SetupSetPlatformPathOverrideA @ stub SetupSetPlatformPathOverrideW -@ stub SetupSetSourceListA -@ stub SetupSetSourceListW +@ stdcall SetupSetSourceListA(long ptr long) +@ stdcall SetupSetSourceListW(long ptr long) @ stdcall SetupTermDefaultQueueCallback(ptr) @ stdcall SetupTerminateFileLog(long) @ stub ShouldDeviceBeExcluded diff --git a/reactos/dll/win32/setupapi/setupapi_private.h b/reactos/dll/win32/setupapi/setupapi_private.h index 5e37cc93342..4fd617e4086 100644 --- a/reactos/dll/win32/setupapi/setupapi_private.h +++ b/reactos/dll/win32/setupapi/setupapi_private.h @@ -221,6 +221,18 @@ extern HINSTANCE hInstance; #define REGPART_RENAME "\\Rename" #define REG_VERSIONCONFLICT "Software\\Microsoft\\VersionConflictManager" +inline static WCHAR *strdupAtoW( const char *str ) +{ + WCHAR *ret = NULL; + if (str) + { + DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); + if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len ); + } + return ret; +} + /* string substitutions */ struct inf_file; diff --git a/reactos/dll/win32/setupapi/stubs.c b/reactos/dll/win32/setupapi/stubs.c index d2617fdf747..589ea5ccac9 100644 --- a/reactos/dll/win32/setupapi/stubs.c +++ b/reactos/dll/win32/setupapi/stubs.c @@ -118,6 +118,23 @@ INT WINAPI SetupPromptReboot(HSPFILEQ FileQueue, HWND Owner, BOOL ScanOnly) return -1; } +/*********************************************************************** + * SetupSetSourceListA (SETUPAPI.@) + */ +BOOL WINAPI SetupSetSourceListA(DWORD flags, PCSTR *list, UINT count) +{ + FIXME("0x%08lx %p %d\n", flags, list, count); + return FALSE; +} + +/*********************************************************************** + * SetupSetSourceListW (SETUPAPI.@) + */ +BOOL WINAPI SetupSetSourceListW(DWORD flags, PCWSTR *list, UINT count) +{ + FIXME("0x%08lx %p %d\n", flags, list, count); + return FALSE; +} /*********************************************************************** * SetupTerminateFileLog(SETUPAPI.@) @@ -128,6 +145,14 @@ BOOL WINAPI SetupTerminateFileLog(HANDLE FileLogHandle) return TRUE; } +/*********************************************************************** + * RegistryDelnode(SETUPAPI.@) + */ +BOOL WINAPI RegistryDelnode(DWORD x, DWORD y) +{ + FIXME("%08lx %08lx: stub\n", x, y); + return FALSE; +} /*********************************************************************** * SetupCloseLog(SETUPAPI.@) diff --git a/reactos/include/psdk/setupapi.h b/reactos/include/psdk/setupapi.h index 281e082e572..710a7adbe8f 100644 --- a/reactos/include/psdk/setupapi.h +++ b/reactos/include/psdk/setupapi.h @@ -1312,6 +1312,8 @@ WINSETUPAPI BOOL WINAPI SetupGetBinaryField(PINFCONTEXT,DWORD,PBYTE,DWORD,LPDWOR WINSETUPAPI DWORD WINAPI SetupGetFieldCount(PINFCONTEXT); WINSETUPAPI DWORD WINAPI SetupGetFileCompressionInfoA(PCSTR,PSTR*,PDWORD,PDWORD,PUINT); WINSETUPAPI DWORD WINAPI SetupGetFileCompressionInfoW(PCWSTR,PWSTR*,PDWORD,PDWORD,PUINT); +WINSETUPAPI BOOL WINAPI SetupGetFileCompressionInfoExA(PCSTR,PSTR,DWORD,PDWORD,PDWORD,PDWORD,PUINT); +WINSETUPAPI BOOL WINAPI SetupGetFileCompressionInfoExW(PCWSTR,PWSTR,DWORD,PDWORD,PDWORD,PDWORD,PUINT); WINSETUPAPI BOOL WINAPI SetupGetInfFileListA(PCSTR,DWORD,PSTR,DWORD,PDWORD); WINSETUPAPI BOOL WINAPI SetupGetInfFileListW(PCWSTR,DWORD,PWSTR,DWORD,PDWORD); WINSETUPAPI BOOL WINAPI SetupGetInfInformationA(LPCVOID,DWORD,PSP_INF_INFORMATION,DWORD,PDWORD); @@ -1524,6 +1526,7 @@ WINSETUPAPI BOOL WINAPI UnmapAndCloseFile(HANDLE, HANDLE, PVOID); #define SetupFreeSourceList SetupFreeSourceListW #define SetupGetBackupInformation SetupGetBackupInformationW #define SetupGetFileCompressionInfo SetupGetFileCompressionInfoW +#define SetupGetFileCompressionInfoEx SetupGetFileCompressionInfoExW #define SetupGetInfFileList SetupGetInfFileListW #define SetupGetInfInformation SetupGetInfInformationW #define SetupGetLineByIndex SetupGetLineByIndexW @@ -1645,6 +1648,7 @@ WINSETUPAPI BOOL WINAPI UnmapAndCloseFile(HANDLE, HANDLE, PVOID); #define SetupFreeSourceList SetupFreeSourceListA #define SetupGetBackupInformation SetupGetBackupInformationA #define SetupGetFileCompressionInfo SetupGetFileCompressionInfoA +#define SetupGetFileCompressionInfoEx SetupGetFileCompressionInfoExA #define SetupGetInfFileList SetupGetInfFileListA #define SetupGetInfInformation SetupGetInfInformationA #define SetupGetLineByIndex SetupGetLineByIndexA