Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmisc.c
Go to the documentation of this file.
00001 /* 00002 * Setupapi miscellaneous functions 00003 * 00004 * Copyright 2005 Eric Kohl 00005 * Copyright 2007 Hans Leidekker 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include "setupapi_private.h" 00023 00024 WINE_DEFAULT_DEBUG_CHANNEL(setupapi); 00025 00026 /* Unicode constants */ 00027 static const WCHAR BackSlash[] = {'\\',0}; 00028 static const WCHAR TranslationRegKey[] = {'\\','V','e','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n',0}; 00029 00030 DWORD 00031 GetFunctionPointer( 00032 IN PWSTR InstallerName, 00033 OUT HMODULE* ModulePointer, 00034 OUT PVOID* FunctionPointer) 00035 { 00036 HMODULE hModule = NULL; 00037 LPSTR FunctionNameA = NULL; 00038 PWCHAR Comma; 00039 DWORD rc; 00040 00041 *ModulePointer = NULL; 00042 *FunctionPointer = NULL; 00043 00044 Comma = strchrW(InstallerName, ','); 00045 if (!Comma) 00046 { 00047 rc = ERROR_INVALID_PARAMETER; 00048 goto cleanup; 00049 } 00050 00051 /* Load library */ 00052 *Comma = '\0'; 00053 hModule = LoadLibraryW(InstallerName); 00054 *Comma = ','; 00055 if (!hModule) 00056 { 00057 rc = GetLastError(); 00058 goto cleanup; 00059 } 00060 00061 /* Skip comma spaces */ 00062 while (*Comma == ',' || isspaceW(*Comma)) 00063 Comma++; 00064 00065 /* W->A conversion for function name */ 00066 FunctionNameA = pSetupUnicodeToMultiByte(Comma, CP_ACP); 00067 if (!FunctionNameA) 00068 { 00069 rc = GetLastError(); 00070 goto cleanup; 00071 } 00072 00073 /* Search function */ 00074 *FunctionPointer = GetProcAddress(hModule, FunctionNameA); 00075 if (!*FunctionPointer) 00076 { 00077 rc = GetLastError(); 00078 goto cleanup; 00079 } 00080 00081 *ModulePointer = hModule; 00082 rc = ERROR_SUCCESS; 00083 00084 cleanup: 00085 if (rc != ERROR_SUCCESS && hModule) 00086 FreeLibrary(hModule); 00087 MyFree(FunctionNameA); 00088 return rc; 00089 } 00090 00091 DWORD 00092 FreeFunctionPointer( 00093 IN HMODULE ModulePointer, 00094 IN PVOID FunctionPointer) 00095 { 00096 if (ModulePointer == NULL) 00097 return ERROR_SUCCESS; 00098 if (FreeLibrary(ModulePointer)) 00099 return ERROR_SUCCESS; 00100 else 00101 return GetLastError(); 00102 } 00103 00104 /************************************************************************** 00105 * MyFree [SETUPAPI.@] 00106 * 00107 * Frees an allocated memory block from the process heap. 00108 * 00109 * PARAMS 00110 * lpMem [I] pointer to memory block which will be freed 00111 * 00112 * RETURNS 00113 * None 00114 */ 00115 VOID WINAPI MyFree(LPVOID lpMem) 00116 { 00117 TRACE("%p\n", lpMem); 00118 HeapFree(GetProcessHeap(), 0, lpMem); 00119 } 00120 00121 00122 /************************************************************************** 00123 * MyMalloc [SETUPAPI.@] 00124 * 00125 * Allocates memory block from the process heap. 00126 * 00127 * PARAMS 00128 * dwSize [I] size of the allocated memory block 00129 * 00130 * RETURNS 00131 * Success: pointer to allocated memory block 00132 * Failure: NULL 00133 */ 00134 LPVOID WINAPI MyMalloc(DWORD dwSize) 00135 { 00136 TRACE("%lu\n", dwSize); 00137 return HeapAlloc(GetProcessHeap(), 0, dwSize); 00138 } 00139 00140 00141 /************************************************************************** 00142 * MyRealloc [SETUPAPI.@] 00143 * 00144 * Changes the size of an allocated memory block or allocates a memory 00145 * block from the process heap. 00146 * 00147 * PARAMS 00148 * lpSrc [I] pointer to memory block which will be resized 00149 * dwSize [I] new size of the memory block 00150 * 00151 * RETURNS 00152 * Success: pointer to the resized memory block 00153 * Failure: NULL 00154 * 00155 * NOTES 00156 * If lpSrc is a NULL-pointer, then MyRealloc allocates a memory 00157 * block like MyMalloc. 00158 */ 00159 LPVOID WINAPI MyRealloc(LPVOID lpSrc, DWORD dwSize) 00160 { 00161 TRACE("%p %lu\n", lpSrc, dwSize); 00162 00163 if (lpSrc == NULL) 00164 return HeapAlloc(GetProcessHeap(), 0, dwSize); 00165 00166 return HeapReAlloc(GetProcessHeap(), 0, lpSrc, dwSize); 00167 } 00168 00169 00170 /************************************************************************** 00171 * pSetupDuplicateString [SETUPAPI.@] 00172 * 00173 * Duplicates a unicode string. 00174 * 00175 * PARAMS 00176 * lpSrc [I] pointer to the unicode string that will be duplicated 00177 * 00178 * RETURNS 00179 * Success: pointer to the duplicated unicode string 00180 * Failure: NULL 00181 * 00182 * NOTES 00183 * Call MyFree() to release the duplicated string. 00184 */ 00185 LPWSTR WINAPI pSetupDuplicateString(LPCWSTR lpSrc) 00186 { 00187 LPWSTR lpDst; 00188 00189 TRACE("%s\n", debugstr_w(lpSrc)); 00190 00191 lpDst = MyMalloc((lstrlenW(lpSrc) + 1) * sizeof(WCHAR)); 00192 if (lpDst == NULL) 00193 return NULL; 00194 00195 strcpyW(lpDst, lpSrc); 00196 00197 return lpDst; 00198 } 00199 00200 00201 /************************************************************************** 00202 * QueryRegistryValue [SETUPAPI.@] 00203 * 00204 * Retrieves value data from the registry and allocates memory for the 00205 * value data. 00206 * 00207 * PARAMS 00208 * hKey [I] Handle of the key to query 00209 * lpValueName [I] Name of value under hkey to query 00210 * lpData [O] Destination for the values contents, 00211 * lpType [O] Destination for the value type 00212 * lpcbData [O] Destination for the size of data 00213 * 00214 * RETURNS 00215 * Success: ERROR_SUCCESS 00216 * Failure: Otherwise 00217 * 00218 * NOTES 00219 * Use MyFree to release the lpData buffer. 00220 */ 00221 LONG WINAPI QueryRegistryValue(HKEY hKey, 00222 LPCWSTR lpValueName, 00223 LPBYTE *lpData, 00224 LPDWORD lpType, 00225 LPDWORD lpcbData) 00226 { 00227 LONG lError; 00228 00229 TRACE("%p %s %p %p %p\n", 00230 hKey, debugstr_w(lpValueName), lpData, lpType, lpcbData); 00231 00232 /* Get required buffer size */ 00233 *lpcbData = 0; 00234 lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, NULL, lpcbData); 00235 if (lError != ERROR_SUCCESS) 00236 return lError; 00237 00238 /* Allocate buffer */ 00239 *lpData = MyMalloc(*lpcbData); 00240 if (*lpData == NULL) 00241 return ERROR_NOT_ENOUGH_MEMORY; 00242 00243 /* Query registry value */ 00244 lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, *lpData, lpcbData); 00245 if (lError != ERROR_SUCCESS) 00246 MyFree(*lpData); 00247 00248 return lError; 00249 } 00250 00251 00252 /************************************************************************** 00253 * pSetupMultiByteToUnicode [SETUPAPI.@] 00254 * 00255 * Converts a multi-byte string to a Unicode string. 00256 * 00257 * PARAMS 00258 * lpMultiByteStr [I] Multi-byte string to be converted 00259 * uCodePage [I] Code page 00260 * 00261 * RETURNS 00262 * Success: pointer to the converted Unicode string 00263 * Failure: NULL 00264 * 00265 * NOTE 00266 * Use MyFree to release the returned Unicode string. 00267 */ 00268 LPWSTR WINAPI pSetupMultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage) 00269 { 00270 LPWSTR lpUnicodeStr; 00271 int nLength; 00272 00273 TRACE("%s %d\n", debugstr_a(lpMultiByteStr), uCodePage); 00274 00275 nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr, 00276 -1, NULL, 0); 00277 if (nLength == 0) 00278 return NULL; 00279 00280 lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR)); 00281 if (lpUnicodeStr == NULL) 00282 { 00283 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00284 return NULL; 00285 } 00286 00287 if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr, 00288 nLength, lpUnicodeStr, nLength)) 00289 { 00290 MyFree(lpUnicodeStr); 00291 return NULL; 00292 } 00293 00294 return lpUnicodeStr; 00295 } 00296 00297 00298 /************************************************************************** 00299 * pSetupUnicodeToMultiByte [SETUPAPI.@] 00300 * 00301 * Converts a Unicode string to a multi-byte string. 00302 * 00303 * PARAMS 00304 * lpUnicodeStr [I] Unicode string to be converted 00305 * uCodePage [I] Code page 00306 * 00307 * RETURNS 00308 * Success: pointer to the converted multi-byte string 00309 * Failure: NULL 00310 * 00311 * NOTE 00312 * Use MyFree to release the returned multi-byte string. 00313 */ 00314 LPSTR WINAPI pSetupUnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage) 00315 { 00316 LPSTR lpMultiByteStr; 00317 int nLength; 00318 00319 TRACE("%s %d\n", debugstr_w(lpUnicodeStr), uCodePage); 00320 00321 nLength = WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1, 00322 NULL, 0, NULL, NULL); 00323 if (nLength == 0) 00324 return NULL; 00325 00326 lpMultiByteStr = MyMalloc(nLength); 00327 if (lpMultiByteStr == NULL) 00328 return NULL; 00329 00330 if (!WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1, 00331 lpMultiByteStr, nLength, NULL, NULL)) 00332 { 00333 MyFree(lpMultiByteStr); 00334 return NULL; 00335 } 00336 00337 return lpMultiByteStr; 00338 } 00339 00340 00341 /************************************************************************** 00342 * DoesUserHavePrivilege [SETUPAPI.@] 00343 * 00344 * Check whether the current user has got a given privilege. 00345 * 00346 * PARAMS 00347 * lpPrivilegeName [I] Name of the privilege to be checked 00348 * 00349 * RETURNS 00350 * Success: TRUE 00351 * Failure: FALSE 00352 */ 00353 BOOL WINAPI DoesUserHavePrivilege(LPCWSTR lpPrivilegeName) 00354 { 00355 HANDLE hToken; 00356 DWORD dwSize; 00357 PTOKEN_PRIVILEGES lpPrivileges; 00358 LUID PrivilegeLuid; 00359 DWORD i; 00360 BOOL bResult = FALSE; 00361 00362 TRACE("%s\n", debugstr_w(lpPrivilegeName)); 00363 00364 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) 00365 return FALSE; 00366 00367 if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize)) 00368 { 00369 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 00370 { 00371 CloseHandle(hToken); 00372 return FALSE; 00373 } 00374 } 00375 00376 lpPrivileges = MyMalloc(dwSize); 00377 if (lpPrivileges == NULL) 00378 { 00379 CloseHandle(hToken); 00380 return FALSE; 00381 } 00382 00383 if (!GetTokenInformation(hToken, TokenPrivileges, lpPrivileges, dwSize, &dwSize)) 00384 { 00385 MyFree(lpPrivileges); 00386 CloseHandle(hToken); 00387 return FALSE; 00388 } 00389 00390 CloseHandle(hToken); 00391 00392 if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, &PrivilegeLuid)) 00393 { 00394 MyFree(lpPrivileges); 00395 return FALSE; 00396 } 00397 00398 for (i = 0; i < lpPrivileges->PrivilegeCount; i++) 00399 { 00400 if (lpPrivileges->Privileges[i].Luid.HighPart == PrivilegeLuid.HighPart && 00401 lpPrivileges->Privileges[i].Luid.LowPart == PrivilegeLuid.LowPart) 00402 { 00403 bResult = TRUE; 00404 } 00405 } 00406 00407 MyFree(lpPrivileges); 00408 00409 return bResult; 00410 } 00411 00412 00413 /************************************************************************** 00414 * pSetupEnablePrivilege [SETUPAPI.@] 00415 * 00416 * Enables or disables one of the current users privileges. 00417 * 00418 * PARAMS 00419 * lpPrivilegeName [I] Name of the privilege to be changed 00420 * bEnable [I] TRUE: Enables the privilege 00421 * FALSE: Disables the privilege 00422 * 00423 * RETURNS 00424 * Success: TRUE 00425 * Failure: FALSE 00426 */ 00427 BOOL WINAPI pSetupEnablePrivilege(LPCWSTR lpPrivilegeName, BOOL bEnable) 00428 { 00429 TOKEN_PRIVILEGES Privileges; 00430 HANDLE hToken; 00431 BOOL bResult; 00432 00433 TRACE("%s %s\n", debugstr_w(lpPrivilegeName), bEnable ? "TRUE" : "FALSE"); 00434 00435 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 00436 return FALSE; 00437 00438 Privileges.PrivilegeCount = 1; 00439 Privileges.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0; 00440 00441 if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, 00442 &Privileges.Privileges[0].Luid)) 00443 { 00444 CloseHandle(hToken); 00445 return FALSE; 00446 } 00447 00448 bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL); 00449 00450 CloseHandle(hToken); 00451 00452 return bResult; 00453 } 00454 00455 00456 /************************************************************************** 00457 * DelayedMove [SETUPAPI.@] 00458 * 00459 * Moves a file upon the next reboot. 00460 * 00461 * PARAMS 00462 * lpExistingFileName [I] Current file name 00463 * lpNewFileName [I] New file name 00464 * 00465 * RETURNS 00466 * Success: TRUE 00467 * Failure: FALSE 00468 */ 00469 BOOL WINAPI DelayedMove(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName) 00470 { 00471 return MoveFileExW(lpExistingFileName, lpNewFileName, 00472 MOVEFILE_REPLACE_EXISTING | MOVEFILE_DELAY_UNTIL_REBOOT); 00473 } 00474 00475 00476 /************************************************************************** 00477 * FileExists [SETUPAPI.@] 00478 * 00479 * Checks whether a file exists. 00480 * 00481 * PARAMS 00482 * lpFileName [I] Name of the file to check 00483 * lpNewFileName [O] Optional information about the existing file 00484 * 00485 * RETURNS 00486 * Success: TRUE 00487 * Failure: FALSE 00488 */ 00489 BOOL WINAPI FileExists(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFileFindData) 00490 { 00491 WIN32_FIND_DATAW FindData; 00492 HANDLE hFind; 00493 UINT uErrorMode; 00494 DWORD dwError; 00495 00496 uErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); 00497 00498 hFind = FindFirstFileW(lpFileName, &FindData); 00499 if (hFind == INVALID_HANDLE_VALUE) 00500 { 00501 dwError = GetLastError(); 00502 SetErrorMode(uErrorMode); 00503 SetLastError(dwError); 00504 return FALSE; 00505 } 00506 00507 FindClose(hFind); 00508 00509 if (lpFileFindData) 00510 memcpy(lpFileFindData, &FindData, sizeof(WIN32_FIND_DATAW)); 00511 00512 SetErrorMode(uErrorMode); 00513 00514 return TRUE; 00515 } 00516 00517 00518 /************************************************************************** 00519 * CaptureStringArg [SETUPAPI.@] 00520 * 00521 * Captures a UNICODE string. 00522 * 00523 * PARAMS 00524 * lpSrc [I] UNICODE string to be captured 00525 * lpDst [O] Pointer to the captured UNICODE string 00526 * 00527 * RETURNS 00528 * Success: ERROR_SUCCESS 00529 * Failure: ERROR_INVALID_PARAMETER 00530 * 00531 * NOTE 00532 * Call MyFree to release the captured UNICODE string. 00533 */ 00534 DWORD WINAPI CaptureStringArg(LPCWSTR pSrc, LPWSTR *pDst) 00535 { 00536 if (pDst == NULL) 00537 return ERROR_INVALID_PARAMETER; 00538 00539 *pDst = pSetupDuplicateString(pSrc); 00540 00541 return ERROR_SUCCESS; 00542 } 00543 00544 00545 /************************************************************************** 00546 * pSetupCaptureAndConvertAnsiArg [SETUPAPI.@] 00547 * 00548 * Captures an ANSI string and converts it to a UNICODE string. 00549 * 00550 * PARAMS 00551 * lpSrc [I] ANSI string to be captured 00552 * lpDst [O] Pointer to the captured UNICODE string 00553 * 00554 * RETURNS 00555 * Success: ERROR_SUCCESS 00556 * Failure: ERROR_INVALID_PARAMETER 00557 * 00558 * NOTE 00559 * Call MyFree to release the captured UNICODE string. 00560 */ 00561 DWORD WINAPI pSetupCaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst) 00562 { 00563 if (pDst == NULL) 00564 return ERROR_INVALID_PARAMETER; 00565 00566 *pDst = pSetupMultiByteToUnicode(pSrc, CP_ACP); 00567 00568 return ERROR_SUCCESS; 00569 } 00570 00571 00572 /************************************************************************** 00573 * pSetupOpenAndMapFileForRead [SETUPAPI.@] 00574 * 00575 * Open and map a file to a buffer. 00576 * 00577 * PARAMS 00578 * lpFileName [I] Name of the file to be opened 00579 * lpSize [O] Pointer to the file size 00580 * lpFile [0] Pointer to the file handle 00581 * lpMapping [0] Pointer to the mapping handle 00582 * lpBuffer [0] Pointer to the file buffer 00583 * 00584 * RETURNS 00585 * Success: ERROR_SUCCESS 00586 * Failure: Other 00587 * 00588 * NOTE 00589 * Call UnmapAndCloseFile to release the file. 00590 */ 00591 DWORD WINAPI pSetupOpenAndMapFileForRead(LPCWSTR lpFileName, 00592 LPDWORD lpSize, 00593 LPHANDLE lpFile, 00594 LPHANDLE lpMapping, 00595 LPVOID *lpBuffer) 00596 { 00597 DWORD dwError; 00598 00599 TRACE("%s %p %p %p %p\n", 00600 debugstr_w(lpFileName), lpSize, lpFile, lpMapping, lpBuffer); 00601 00602 *lpFile = CreateFileW(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, 00603 OPEN_EXISTING, 0, NULL); 00604 if (*lpFile == INVALID_HANDLE_VALUE) 00605 return GetLastError(); 00606 00607 *lpSize = GetFileSize(*lpFile, NULL); 00608 if (*lpSize == INVALID_FILE_SIZE) 00609 { 00610 dwError = GetLastError(); 00611 CloseHandle(*lpFile); 00612 return dwError; 00613 } 00614 00615 *lpMapping = CreateFileMappingW(*lpFile, NULL, PAGE_READONLY, 0, 00616 *lpSize, NULL); 00617 if (*lpMapping == NULL) 00618 { 00619 dwError = GetLastError(); 00620 CloseHandle(*lpFile); 00621 return dwError; 00622 } 00623 00624 *lpBuffer = MapViewOfFile(*lpMapping, FILE_MAP_READ, 0, 0, *lpSize); 00625 if (*lpBuffer == NULL) 00626 { 00627 dwError = GetLastError(); 00628 CloseHandle(*lpMapping); 00629 CloseHandle(*lpFile); 00630 return dwError; 00631 } 00632 00633 return ERROR_SUCCESS; 00634 } 00635 00636 00637 /************************************************************************** 00638 * pSetupUnmapAndCloseFile [SETUPAPI.@] 00639 * 00640 * Unmap and close a mapped file. 00641 * 00642 * PARAMS 00643 * hFile [I] Handle to the file 00644 * hMapping [I] Handle to the file mapping 00645 * lpBuffer [I] Pointer to the file buffer 00646 * 00647 * RETURNS 00648 * Success: TRUE 00649 * Failure: FALSE 00650 */ 00651 BOOL WINAPI pSetupUnmapAndCloseFile(HANDLE hFile, HANDLE hMapping, LPVOID lpBuffer) 00652 { 00653 TRACE("%p %p %p\n", 00654 hFile, hMapping, lpBuffer); 00655 00656 if (!UnmapViewOfFile(lpBuffer)) 00657 return FALSE; 00658 00659 if (!CloseHandle(hMapping)) 00660 return FALSE; 00661 00662 if (!CloseHandle(hFile)) 00663 return FALSE; 00664 00665 return TRUE; 00666 } 00667 00668 00669 /************************************************************************** 00670 * StampFileSecurity [SETUPAPI.@] 00671 * 00672 * Assign a new security descriptor to the given file. 00673 * 00674 * PARAMS 00675 * lpFileName [I] Name of the file 00676 * pSecurityDescriptor [I] New security descriptor 00677 * 00678 * RETURNS 00679 * Success: ERROR_SUCCESS 00680 * Failure: other 00681 */ 00682 DWORD WINAPI StampFileSecurity(LPCWSTR lpFileName, PSECURITY_DESCRIPTOR pSecurityDescriptor) 00683 { 00684 TRACE("%s %p\n", debugstr_w(lpFileName), pSecurityDescriptor); 00685 00686 if (!SetFileSecurityW(lpFileName, OWNER_SECURITY_INFORMATION | 00687 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 00688 pSecurityDescriptor)) 00689 return GetLastError(); 00690 00691 return ERROR_SUCCESS; 00692 } 00693 00694 00695 /************************************************************************** 00696 * TakeOwnershipOfFile [SETUPAPI.@] 00697 * 00698 * Takes the ownership of the given file. 00699 * 00700 * PARAMS 00701 * lpFileName [I] Name of the file 00702 * 00703 * RETURNS 00704 * Success: ERROR_SUCCESS 00705 * Failure: other 00706 */ 00707 DWORD WINAPI TakeOwnershipOfFile(LPCWSTR lpFileName) 00708 { 00709 SECURITY_DESCRIPTOR SecDesc; 00710 HANDLE hToken = NULL; 00711 PTOKEN_OWNER pOwner = NULL; 00712 DWORD dwError; 00713 DWORD dwSize; 00714 00715 TRACE("%s\n", debugstr_w(lpFileName)); 00716 00717 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) 00718 return GetLastError(); 00719 00720 if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &dwSize)) 00721 { 00722 goto fail; 00723 } 00724 00725 pOwner = (PTOKEN_OWNER)MyMalloc(dwSize); 00726 if (pOwner == NULL) 00727 { 00728 CloseHandle(hToken); 00729 return ERROR_NOT_ENOUGH_MEMORY; 00730 } 00731 00732 if (!GetTokenInformation(hToken, TokenOwner, pOwner, dwSize, &dwSize)) 00733 { 00734 goto fail; 00735 } 00736 00737 if (!InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION)) 00738 { 00739 goto fail; 00740 } 00741 00742 if (!SetSecurityDescriptorOwner(&SecDesc, pOwner->Owner, FALSE)) 00743 { 00744 goto fail; 00745 } 00746 00747 if (!SetFileSecurityW(lpFileName, OWNER_SECURITY_INFORMATION, &SecDesc)) 00748 { 00749 goto fail; 00750 } 00751 00752 MyFree(pOwner); 00753 CloseHandle(hToken); 00754 00755 return ERROR_SUCCESS; 00756 00757 fail:; 00758 dwError = GetLastError(); 00759 00760 MyFree(pOwner); 00761 00762 if (hToken != NULL) 00763 CloseHandle(hToken); 00764 00765 return dwError; 00766 } 00767 00768 00769 /************************************************************************** 00770 * RetreiveFileSecurity [SETUPAPI.@] 00771 * 00772 * Retrieve the security descriptor that is associated with the given file. 00773 * 00774 * PARAMS 00775 * lpFileName [I] Name of the file 00776 * 00777 * RETURNS 00778 * Success: ERROR_SUCCESS 00779 * Failure: other 00780 */ 00781 DWORD WINAPI RetreiveFileSecurity(LPCWSTR lpFileName, 00782 PSECURITY_DESCRIPTOR *pSecurityDescriptor) 00783 { 00784 PSECURITY_DESCRIPTOR SecDesc; 00785 DWORD dwSize = 0x100; 00786 DWORD dwError; 00787 00788 TRACE("%s %p\n", debugstr_w(lpFileName), pSecurityDescriptor); 00789 00790 SecDesc = MyMalloc(dwSize); 00791 if (SecDesc == NULL) 00792 return ERROR_NOT_ENOUGH_MEMORY; 00793 00794 if (GetFileSecurityW(lpFileName, OWNER_SECURITY_INFORMATION | 00795 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 00796 SecDesc, dwSize, &dwSize)) 00797 { 00798 *pSecurityDescriptor = SecDesc; 00799 return ERROR_SUCCESS; 00800 } 00801 00802 dwError = GetLastError(); 00803 if (dwError != ERROR_INSUFFICIENT_BUFFER) 00804 { 00805 MyFree(SecDesc); 00806 return dwError; 00807 } 00808 00809 SecDesc = MyRealloc(SecDesc, dwSize); 00810 if (SecDesc == NULL) 00811 return ERROR_NOT_ENOUGH_MEMORY; 00812 00813 if (GetFileSecurityW(lpFileName, OWNER_SECURITY_INFORMATION | 00814 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 00815 SecDesc, dwSize, &dwSize)) 00816 { 00817 *pSecurityDescriptor = SecDesc; 00818 return ERROR_SUCCESS; 00819 } 00820 00821 dwError = GetLastError(); 00822 MyFree(SecDesc); 00823 00824 return dwError; 00825 } 00826 00827 00828 static DWORD global_flags = 0; /* FIXME: what should be in here? */ 00829 00830 /*********************************************************************** 00831 * pSetupGetGlobalFlags (SETUPAPI.@) 00832 */ 00833 DWORD WINAPI pSetupGetGlobalFlags(void) 00834 { 00835 FIXME( "stub\n" ); 00836 return global_flags; 00837 } 00838 00839 00840 /*********************************************************************** 00841 * pSetupSetGlobalFlags (SETUPAPI.@) 00842 */ 00843 void WINAPI pSetupSetGlobalFlags( DWORD flags ) 00844 { 00845 global_flags = flags; 00846 } 00847 00848 /*********************************************************************** 00849 * AssertFail (SETUPAPI.@) 00850 * 00851 * Shows an assert fail error messagebox 00852 * 00853 * PARAMS 00854 * lpFile [I] file where assert failed 00855 * uLine [I] line number in file 00856 * lpMessage [I] assert message 00857 * 00858 */ 00859 VOID WINAPI AssertFail(LPSTR lpFile, UINT uLine, LPSTR lpMessage) 00860 { 00861 CHAR szModule[MAX_PATH]; 00862 CHAR szBuffer[2048]; 00863 LPSTR lpName; 00864 // LPSTR lpBuffer; 00865 00866 TRACE("%s %u %s\n", lpFile, uLine, lpMessage); 00867 00868 GetModuleFileNameA(hInstance, szModule, MAX_PATH); 00869 lpName = strrchr(szModule, '\\'); 00870 if (lpName != NULL) 00871 lpName++; 00872 else 00873 lpName = szModule; 00874 00875 wsprintfA(szBuffer, 00876 "Assertion failure at line %u in file %s: %s\n\nCall DebugBreak()?", 00877 uLine, lpFile, lpMessage); 00878 00879 if (MessageBoxA(NULL, szBuffer, lpName, MB_SETFOREGROUND | 00880 MB_TASKMODAL | MB_ICONERROR | MB_YESNO) == IDYES) 00881 DebugBreak(); 00882 } 00883 00884 00885 /************************************************************************** 00886 * GetSetFileTimestamp [SETUPAPI.@] 00887 * 00888 * Gets or sets a files timestamp. 00889 * 00890 * PARAMS 00891 * lpFileName [I] File name 00892 * lpCreationTime [I/O] Creation time 00893 * lpLastAccessTime [I/O] Last access time 00894 * lpLastWriteTime [I/O] Last write time 00895 * bSetFileTime [I] TRUE: Set file times 00896 * FALSE: Get file times 00897 * 00898 * RETURNS 00899 * Success: ERROR_SUCCESS 00900 * Failure: other 00901 */ 00902 DWORD WINAPI GetSetFileTimestamp(LPCWSTR lpFileName, 00903 LPFILETIME lpCreationTime, 00904 LPFILETIME lpLastAccessTime, 00905 LPFILETIME lpLastWriteTime, 00906 BOOLEAN bSetFileTime) 00907 { 00908 HANDLE hFile; 00909 BOOLEAN bRet; 00910 DWORD dwError = ERROR_SUCCESS; 00911 00912 TRACE("%s %p %p %p %x\n", debugstr_w(lpFileName), lpCreationTime, 00913 lpLastAccessTime, lpLastWriteTime, bSetFileTime); 00914 00915 hFile = CreateFileW(lpFileName, 00916 bSetFileTime ? GENERIC_WRITE : GENERIC_READ, 00917 FILE_SHARE_READ | FILE_SHARE_WRITE, 00918 NULL, 00919 OPEN_EXISTING, 00920 0, 00921 NULL); 00922 00923 if (hFile == INVALID_HANDLE_VALUE) 00924 return GetLastError(); 00925 00926 if (bSetFileTime) 00927 bRet = SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime); 00928 else 00929 bRet = GetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime); 00930 00931 if (bRet == FALSE) 00932 dwError = GetLastError(); 00933 00934 CloseHandle(hFile); 00935 00936 return dwError; 00937 } 00938 00939 00940 /************************************************************************** 00941 * pSetupGetFileTitle [SETUPAPI.@] 00942 * 00943 * Returns a pointer to the last part of a fully qualified file name. 00944 * 00945 * PARAMS 00946 * lpFileName [I] File name 00947 * 00948 * RETURNS 00949 * Pointer to a files name. 00950 */ 00951 LPWSTR WINAPI 00952 pSetupGetFileTitle(LPCWSTR lpFileName) 00953 { 00954 LPWSTR ptr; 00955 LPWSTR ret; 00956 WCHAR c; 00957 00958 TRACE("%s\n", debugstr_w(lpFileName)); 00959 00960 ptr = (LPWSTR)lpFileName; 00961 ret = ptr; 00962 while (TRUE) 00963 { 00964 c = *ptr; 00965 00966 if (c == 0) 00967 break; 00968 00969 ptr++; 00970 if (c == (WCHAR)'\\' || c == (WCHAR)'/' || c == (WCHAR)':') 00971 ret = ptr; 00972 } 00973 00974 return ret; 00975 } 00976 00977 00978 /************************************************************************** 00979 * pSetupConcatenatePaths [SETUPAPI.@] 00980 * 00981 * Concatenates two paths. 00982 * 00983 * PARAMS 00984 * lpPath [I/O] Path to append path to 00985 * lpAppend [I] Path to append 00986 * dwBufferSize [I] Size of the path buffer 00987 * lpRequiredSize [O] Required size for the concatenated path. Optional 00988 * 00989 * RETURNS 00990 * Success: TRUE 00991 * Failure: FALSE 00992 */ 00993 BOOL WINAPI 00994 pSetupConcatenatePaths(LPWSTR lpPath, 00995 LPCWSTR lpAppend, 00996 DWORD dwBufferSize, 00997 LPDWORD lpRequiredSize) 00998 { 00999 DWORD dwPathSize; 01000 DWORD dwAppendSize; 01001 DWORD dwTotalSize; 01002 BOOL bBackslash = FALSE; 01003 01004 TRACE("%s %s %lu %p\n", debugstr_w(lpPath), debugstr_w(lpAppend), 01005 dwBufferSize, lpRequiredSize); 01006 01007 dwPathSize = lstrlenW(lpPath); 01008 01009 /* Ignore trailing backslash */ 01010 if (lpPath[dwPathSize - 1] == (WCHAR)'\\') 01011 dwPathSize--; 01012 01013 dwAppendSize = lstrlenW(lpAppend); 01014 01015 /* Does the source string have a leading backslash? */ 01016 if (lpAppend[0] == (WCHAR)'\\') 01017 { 01018 bBackslash = TRUE; 01019 dwAppendSize--; 01020 } 01021 01022 dwTotalSize = dwPathSize + dwAppendSize + 2; 01023 if (lpRequiredSize != NULL) 01024 *lpRequiredSize = dwTotalSize; 01025 01026 /* Append a backslash to the destination string */ 01027 if (bBackslash == FALSE) 01028 { 01029 if (dwPathSize < dwBufferSize) 01030 { 01031 lpPath[dwPathSize - 1] = (WCHAR)'\\'; 01032 dwPathSize++; 01033 } 01034 } 01035 01036 if (dwPathSize + dwAppendSize < dwBufferSize) 01037 { 01038 lstrcpynW(&lpPath[dwPathSize], 01039 lpAppend, 01040 dwAppendSize); 01041 } 01042 01043 if (dwBufferSize >= dwTotalSize) 01044 lpPath[dwTotalSize - 1] = 0; 01045 01046 return (dwBufferSize >= dwTotalSize); 01047 } 01048 01049 01050 /************************************************************************** 01051 * pSetupCenterWindowRelativeToParent [SETUPAPI.@] 01052 * 01053 * Centers a window relative to its parent. 01054 * 01055 * PARAMS 01056 * hwnd [I] Window to center. 01057 * 01058 * RETURNS 01059 * None 01060 */ 01061 VOID WINAPI 01062 pSetupCenterWindowRelativeToParent(HWND hwnd) 01063 { 01064 HWND hwndOwner; 01065 POINT ptOrigin; 01066 RECT rcWindow; 01067 RECT rcOwner; 01068 INT nWindowWidth, nWindowHeight; 01069 INT nOwnerWidth, nOwnerHeight; 01070 INT posX, posY; 01071 01072 hwndOwner = GetWindow(hwnd, GW_OWNER); 01073 if (hwndOwner == NULL) 01074 return; 01075 01076 ptOrigin.x = 0; 01077 ptOrigin.y = 0; 01078 ClientToScreen(hwndOwner, &ptOrigin); 01079 01080 GetWindowRect(hwnd, &rcWindow); 01081 GetClientRect(hwndOwner, &rcOwner); 01082 01083 nWindowWidth = rcWindow.right - rcWindow.left; 01084 nWindowHeight = rcWindow.bottom - rcWindow.top; 01085 01086 nOwnerWidth = rcOwner.right - rcOwner.left; 01087 nOwnerHeight = rcOwner.bottom - rcOwner.top; 01088 01089 posX = ((nOwnerWidth - nWindowWidth) / 2) + ptOrigin.x; 01090 posY = ((nOwnerHeight - nWindowHeight) / 2) + ptOrigin.y; 01091 01092 MoveWindow(hwnd, posX, posY, nWindowHeight, nWindowWidth, 0); 01093 } 01094 01095 01096 /************************************************************************** 01097 * pSetupGetVersionInfoFromImage [SETUPAPI.@] 01098 * 01099 * Retrieves version information for a given file. 01100 * 01101 * PARAMS 01102 * lpFileName [I] File name 01103 * lpFileVersion [O] Pointer to the full file version 01104 * lpVersionVarSize [O] Pointer to the size of the variable version 01105 * information 01106 * 01107 * RETURNS 01108 * Success: TRUE 01109 * Failure: FALSE 01110 */ 01111 BOOL WINAPI 01112 pSetupGetVersionInfoFromImage(LPWSTR lpFileName, 01113 PULARGE_INTEGER lpFileVersion, 01114 LPWORD lpVersionVarSize) 01115 { 01116 DWORD dwHandle; 01117 DWORD dwSize; 01118 LPVOID lpInfo; 01119 UINT uSize; 01120 VS_FIXEDFILEINFO *lpFixedInfo; 01121 LPWORD lpVarSize; 01122 01123 dwSize = GetFileVersionInfoSizeW(lpFileName, &dwHandle); 01124 if (dwSize == 0) 01125 return FALSE; 01126 01127 lpInfo = MyMalloc(dwSize); 01128 if (lpInfo == NULL) 01129 return FALSE; 01130 01131 if (!GetFileVersionInfoW(lpFileName, 0, dwSize, lpInfo)) 01132 { 01133 MyFree(lpInfo); 01134 return FALSE; 01135 } 01136 01137 if (!VerQueryValueW(lpInfo, BackSlash, 01138 (LPVOID*)&lpFixedInfo, &uSize)) 01139 { 01140 MyFree(lpInfo); 01141 return FALSE; 01142 } 01143 01144 lpFileVersion->LowPart = lpFixedInfo->dwFileVersionLS; 01145 lpFileVersion->HighPart = lpFixedInfo->dwFileVersionMS; 01146 01147 *lpVersionVarSize = 0; 01148 if (!VerQueryValueW(lpInfo, TranslationRegKey, 01149 (LPVOID*)&lpVarSize, &uSize)) 01150 { 01151 MyFree(lpInfo); 01152 return TRUE; 01153 } 01154 01155 if (uSize >= 4) 01156 { 01157 *lpVersionVarSize = *lpVarSize; 01158 } 01159 01160 MyFree(lpInfo); 01161 01162 return TRUE; 01163 } 01164 01165 /*********************************************************************** 01166 * SetupUninstallOEMInfW (SETUPAPI.@) 01167 */ 01168 BOOL WINAPI SetupUninstallOEMInfW( PCWSTR inf_file, DWORD flags, PVOID reserved ) 01169 { 01170 static const WCHAR infW[] = {'\\','i','n','f','\\',0}; 01171 WCHAR target[MAX_PATH]; 01172 01173 TRACE("%s, 0x%08x, %p\n", debugstr_w(inf_file), flags, reserved); 01174 01175 if (!inf_file) 01176 { 01177 SetLastError(ERROR_INVALID_PARAMETER); 01178 return FALSE; 01179 } 01180 01181 if (!GetWindowsDirectoryW( target, sizeof(target)/sizeof(WCHAR) )) return FALSE; 01182 01183 strcatW( target, infW ); 01184 strcatW( target, inf_file ); 01185 01186 if (flags & SUOI_FORCEDELETE) 01187 return DeleteFileW(target); 01188 01189 FIXME("not deleting %s\n", debugstr_w(target)); 01190 01191 return TRUE; 01192 } 01193 01194 /*********************************************************************** 01195 * SetupUninstallOEMInfA (SETUPAPI.@) 01196 */ 01197 BOOL WINAPI SetupUninstallOEMInfA( PCSTR inf_file, DWORD flags, PVOID reserved ) 01198 { 01199 BOOL ret; 01200 WCHAR *inf_fileW = NULL; 01201 01202 TRACE("%s, 0x%08x, %p\n", debugstr_a(inf_file), flags, reserved); 01203 01204 if (inf_file && !(inf_fileW = strdupAtoW( inf_file ))) return FALSE; 01205 ret = SetupUninstallOEMInfW( inf_fileW, flags, reserved ); 01206 HeapFree( GetProcessHeap(), 0, inf_fileW ); 01207 return ret; 01208 } 01209 01210 /*********************************************************************** 01211 * InstallCatalog (SETUPAPI.@) 01212 */ 01213 DWORD WINAPI InstallCatalog( LPCSTR catalog, LPCSTR basename, LPSTR fullname ) 01214 { 01215 FIXME("%s, %s, %p\n", debugstr_a(catalog), debugstr_a(basename), fullname); 01216 return 0; 01217 } 01218 01219 static UINT detect_compression_type( LPCWSTR file ) 01220 { 01221 DWORD size; 01222 HANDLE handle; 01223 UINT type = FILE_COMPRESSION_NONE; 01224 static const BYTE LZ_MAGIC[] = { 0x53, 0x5a, 0x44, 0x44, 0x88, 0xf0, 0x27, 0x33 }; 01225 static const BYTE MSZIP_MAGIC[] = { 0x4b, 0x57, 0x41, 0x4a }; 01226 static const BYTE NTCAB_MAGIC[] = { 0x4d, 0x53, 0x43, 0x46 }; 01227 BYTE buffer[8]; 01228 01229 handle = CreateFileW( file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); 01230 if (handle == INVALID_HANDLE_VALUE) 01231 { 01232 ERR("cannot open file %s\n", debugstr_w(file)); 01233 return FILE_COMPRESSION_NONE; 01234 } 01235 if (!ReadFile( handle, buffer, sizeof(buffer), &size, NULL ) || size != sizeof(buffer)) 01236 { 01237 CloseHandle( handle ); 01238 return FILE_COMPRESSION_NONE; 01239 } 01240 if (!memcmp( buffer, LZ_MAGIC, sizeof(LZ_MAGIC) )) type = FILE_COMPRESSION_WINLZA; 01241 else if (!memcmp( buffer, MSZIP_MAGIC, sizeof(MSZIP_MAGIC) )) type = FILE_COMPRESSION_MSZIP; 01242 else if (!memcmp( buffer, NTCAB_MAGIC, sizeof(NTCAB_MAGIC) )) type = FILE_COMPRESSION_MSZIP; /* not a typo */ 01243 01244 CloseHandle( handle ); 01245 return type; 01246 } 01247 01248 static BOOL get_file_size( LPCWSTR file, DWORD *size ) 01249 { 01250 HANDLE handle; 01251 01252 handle = CreateFileW( file, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); 01253 if (handle == INVALID_HANDLE_VALUE) 01254 { 01255 ERR("cannot open file %s\n", debugstr_w(file)); 01256 return FALSE; 01257 } 01258 *size = GetFileSize( handle, NULL ); 01259 CloseHandle( handle ); 01260 return TRUE; 01261 } 01262 01263 static BOOL get_file_sizes_none( LPCWSTR source, DWORD *source_size, DWORD *target_size ) 01264 { 01265 DWORD size; 01266 01267 if (!get_file_size( source, &size )) return FALSE; 01268 if (source_size) *source_size = size; 01269 if (target_size) *target_size = size; 01270 return TRUE; 01271 } 01272 01273 static BOOL get_file_sizes_lz( LPCWSTR source, DWORD *source_size, DWORD *target_size ) 01274 { 01275 DWORD size; 01276 BOOL ret = TRUE; 01277 01278 if (source_size) 01279 { 01280 if (!get_file_size( source, &size )) ret = FALSE; 01281 else *source_size = size; 01282 } 01283 if (target_size) 01284 { 01285 INT file; 01286 OFSTRUCT of; 01287 01288 if ((file = LZOpenFileW( (LPWSTR)source, &of, OF_READ )) < 0) 01289 { 01290 ERR("cannot open source file for reading\n"); 01291 return FALSE; 01292 } 01293 *target_size = LZSeek( file, 0, 2 ); 01294 LZClose( file ); 01295 } 01296 return ret; 01297 } 01298 01299 static UINT CALLBACK file_compression_info_callback( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 ) 01300 { 01301 DWORD *size = context; 01302 FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)param1; 01303 01304 switch (notification) 01305 { 01306 case SPFILENOTIFY_FILEINCABINET: 01307 { 01308 *size = info->FileSize; 01309 return FILEOP_SKIP; 01310 } 01311 default: return NO_ERROR; 01312 } 01313 } 01314 01315 static BOOL get_file_sizes_cab( LPCWSTR source, DWORD *source_size, DWORD *target_size ) 01316 { 01317 DWORD size; 01318 BOOL ret = TRUE; 01319 01320 if (source_size) 01321 { 01322 if (!get_file_size( source, &size )) ret = FALSE; 01323 else *source_size = size; 01324 } 01325 if (target_size) 01326 { 01327 ret = SetupIterateCabinetW( source, 0, file_compression_info_callback, target_size ); 01328 } 01329 return ret; 01330 } 01331 01332 /*********************************************************************** 01333 * SetupGetFileCompressionInfoExA (SETUPAPI.@) 01334 * 01335 * See SetupGetFileCompressionInfoExW. 01336 */ 01337 BOOL WINAPI SetupGetFileCompressionInfoExA( PCSTR source, PSTR name, DWORD len, PDWORD required, 01338 PDWORD source_size, PDWORD target_size, PUINT type ) 01339 { 01340 BOOL ret; 01341 WCHAR *nameW = NULL, *sourceW = NULL; 01342 DWORD nb_chars = 0; 01343 LPSTR nameA; 01344 01345 TRACE("%s, %p, %d, %p, %p, %p, %p\n", debugstr_a(source), name, len, required, 01346 source_size, target_size, type); 01347 01348 if (!source || !(sourceW = pSetupMultiByteToUnicode( source, CP_ACP ))) return FALSE; 01349 01350 if (name) 01351 { 01352 ret = SetupGetFileCompressionInfoExW( sourceW, NULL, 0, &nb_chars, NULL, NULL, NULL ); 01353 if (!(nameW = HeapAlloc( GetProcessHeap(), 0, nb_chars * sizeof(WCHAR) ))) 01354 { 01355 MyFree( sourceW ); 01356 return FALSE; 01357 } 01358 } 01359 ret = SetupGetFileCompressionInfoExW( sourceW, nameW, nb_chars, &nb_chars, source_size, target_size, type ); 01360 if (ret) 01361 { 01362 if ((nameA = pSetupUnicodeToMultiByte( nameW, CP_ACP ))) 01363 { 01364 if (name && len >= nb_chars) lstrcpyA( name, nameA ); 01365 else 01366 { 01367 SetLastError( ERROR_INSUFFICIENT_BUFFER ); 01368 ret = FALSE; 01369 } 01370 MyFree( nameA ); 01371 } 01372 } 01373 if (required) *required = nb_chars; 01374 HeapFree( GetProcessHeap(), 0, nameW ); 01375 MyFree( sourceW ); 01376 01377 return ret; 01378 } 01379 01380 /*********************************************************************** 01381 * SetupGetFileCompressionInfoExW (SETUPAPI.@) 01382 * 01383 * Get compression type and compressed/uncompressed sizes of a given file. 01384 * 01385 * PARAMS 01386 * source [I] File to examine. 01387 * name [O] Actual filename used. 01388 * len [I] Length in characters of 'name' buffer. 01389 * required [O] Number of characters written to 'name'. 01390 * source_size [O] Size of compressed file. 01391 * target_size [O] Size of uncompressed file. 01392 * type [O] Compression type. 01393 * 01394 * RETURNS 01395 * Success: TRUE 01396 * Failure: FALSE 01397 */ 01398 BOOL WINAPI SetupGetFileCompressionInfoExW( PCWSTR source, PWSTR name, DWORD len, PDWORD required, 01399 PDWORD source_size, PDWORD target_size, PUINT type ) 01400 { 01401 UINT comp; 01402 BOOL ret = FALSE; 01403 DWORD source_len; 01404 01405 TRACE("%s, %p, %d, %p, %p, %p, %p\n", debugstr_w(source), name, len, required, 01406 source_size, target_size, type); 01407 01408 if (!source) return FALSE; 01409 01410 source_len = lstrlenW( source ) + 1; 01411 if (required) *required = source_len; 01412 if (name && len >= source_len) 01413 { 01414 lstrcpyW( name, source ); 01415 ret = TRUE; 01416 } 01417 else return FALSE; 01418 01419 comp = detect_compression_type( source ); 01420 if (type) *type = comp; 01421 01422 switch (comp) 01423 { 01424 case FILE_COMPRESSION_MSZIP: 01425 case FILE_COMPRESSION_NTCAB: ret = get_file_sizes_cab( source, source_size, target_size ); break; 01426 case FILE_COMPRESSION_NONE: ret = get_file_sizes_none( source, source_size, target_size ); break; 01427 case FILE_COMPRESSION_WINLZA: ret = get_file_sizes_lz( source, source_size, target_size ); break; 01428 default: break; 01429 } 01430 return ret; 01431 } 01432 01433 /*********************************************************************** 01434 * SetupGetFileCompressionInfoA (SETUPAPI.@) 01435 * 01436 * See SetupGetFileCompressionInfoW. 01437 */ 01438 DWORD WINAPI SetupGetFileCompressionInfoA( PCSTR source, PSTR *name, PDWORD source_size, 01439 PDWORD target_size, PUINT type ) 01440 { 01441 BOOL ret; 01442 DWORD error, required; 01443 LPSTR actual_name; 01444 01445 TRACE("%s, %p, %p, %p, %p\n", debugstr_a(source), name, source_size, target_size, type); 01446 01447 if (!source || !name || !source_size || !target_size || !type) 01448 return ERROR_INVALID_PARAMETER; 01449 01450 ret = SetupGetFileCompressionInfoExA( source, NULL, 0, &required, NULL, NULL, NULL ); 01451 if (!(actual_name = MyMalloc( required ))) return ERROR_NOT_ENOUGH_MEMORY; 01452 01453 ret = SetupGetFileCompressionInfoExA( source, actual_name, required, &required, 01454 source_size, target_size, type ); 01455 if (!ret) 01456 { 01457 error = GetLastError(); 01458 MyFree( actual_name ); 01459 return error; 01460 } 01461 *name = actual_name; 01462 return ERROR_SUCCESS; 01463 } 01464 01465 /*********************************************************************** 01466 * SetupGetFileCompressionInfoW (SETUPAPI.@) 01467 * 01468 * Get compression type and compressed/uncompressed sizes of a given file. 01469 * 01470 * PARAMS 01471 * source [I] File to examine. 01472 * name [O] Actual filename used. 01473 * source_size [O] Size of compressed file. 01474 * target_size [O] Size of uncompressed file. 01475 * type [O] Compression type. 01476 * 01477 * RETURNS 01478 * Success: ERROR_SUCCESS 01479 * Failure: Win32 error code. 01480 */ 01481 DWORD WINAPI SetupGetFileCompressionInfoW( PCWSTR source, PWSTR *name, PDWORD source_size, 01482 PDWORD target_size, PUINT type ) 01483 { 01484 BOOL ret; 01485 DWORD error, required; 01486 LPWSTR actual_name; 01487 01488 TRACE("%s, %p, %p, %p, %p\n", debugstr_w(source), name, source_size, target_size, type); 01489 01490 if (!source || !name || !source_size || !target_size || !type) 01491 return ERROR_INVALID_PARAMETER; 01492 01493 ret = SetupGetFileCompressionInfoExW( source, NULL, 0, &required, NULL, NULL, NULL ); 01494 if (!(actual_name = MyMalloc( required ))) return ERROR_NOT_ENOUGH_MEMORY; 01495 01496 ret = SetupGetFileCompressionInfoExW( source, actual_name, required, &required, 01497 source_size, target_size, type ); 01498 if (!ret) 01499 { 01500 error = GetLastError(); 01501 MyFree( actual_name ); 01502 return error; 01503 } 01504 *name = actual_name; 01505 return ERROR_SUCCESS; 01506 } 01507 01508 static DWORD decompress_file_lz( LPCWSTR source, LPCWSTR target ) 01509 { 01510 DWORD ret; 01511 LONG error; 01512 INT src, dst; 01513 OFSTRUCT sof, dof; 01514 01515 if ((src = LZOpenFileW( (LPWSTR)source, &sof, OF_READ )) < 0) 01516 { 01517 ERR("cannot open source file for reading\n"); 01518 return ERROR_FILE_NOT_FOUND; 01519 } 01520 if ((dst = LZOpenFileW( (LPWSTR)target, &dof, OF_CREATE )) < 0) 01521 { 01522 ERR("cannot open target file for writing\n"); 01523 LZClose( src ); 01524 return ERROR_FILE_NOT_FOUND; 01525 } 01526 if ((error = LZCopy( src, dst )) >= 0) ret = ERROR_SUCCESS; 01527 else 01528 { 01529 WARN("failed to decompress file %d\n", error); 01530 ret = ERROR_INVALID_DATA; 01531 } 01532 01533 LZClose( src ); 01534 LZClose( dst ); 01535 return ret; 01536 } 01537 01538 static UINT CALLBACK decompress_or_copy_callback( PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2 ) 01539 { 01540 FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)param1; 01541 01542 switch (notification) 01543 { 01544 case SPFILENOTIFY_FILEINCABINET: 01545 { 01546 LPCWSTR filename, targetname = context; 01547 WCHAR *p; 01548 01549 if ((p = strrchrW( targetname, '\\' ))) filename = p + 1; 01550 else filename = targetname; 01551 01552 if (!lstrcmpiW( filename, info->NameInCabinet )) 01553 { 01554 strcpyW( info->FullTargetName, targetname ); 01555 return FILEOP_DOIT; 01556 } 01557 return FILEOP_SKIP; 01558 } 01559 default: return NO_ERROR; 01560 } 01561 } 01562 01563 static DWORD decompress_file_cab( LPCWSTR source, LPCWSTR target ) 01564 { 01565 BOOL ret; 01566 01567 ret = SetupIterateCabinetW( source, 0, decompress_or_copy_callback, (PVOID)target ); 01568 01569 if (ret) return ERROR_SUCCESS; 01570 else return GetLastError(); 01571 } 01572 01573 /*********************************************************************** 01574 * SetupDecompressOrCopyFileA (SETUPAPI.@) 01575 * 01576 * See SetupDecompressOrCopyFileW. 01577 */ 01578 DWORD WINAPI SetupDecompressOrCopyFileA( PCSTR source, PCSTR target, PUINT type ) 01579 { 01580 DWORD ret = FALSE; 01581 WCHAR *sourceW = NULL, *targetW = NULL; 01582 01583 if (source && !(sourceW = pSetupMultiByteToUnicode( source, CP_ACP ))) return FALSE; 01584 if (target && !(targetW = pSetupMultiByteToUnicode( target, CP_ACP ))) 01585 { 01586 MyFree( sourceW ); 01587 return ERROR_NOT_ENOUGH_MEMORY; 01588 } 01589 01590 ret = SetupDecompressOrCopyFileW( sourceW, targetW, type ); 01591 01592 MyFree( sourceW ); 01593 MyFree( targetW ); 01594 01595 return ret; 01596 } 01597 01598 /*********************************************************************** 01599 * SetupDecompressOrCopyFileW (SETUPAPI.@) 01600 * 01601 * Copy a file and decompress it if needed. 01602 * 01603 * PARAMS 01604 * source [I] File to copy. 01605 * target [I] Filename of the copy. 01606 * type [I] Compression type. 01607 * 01608 * RETURNS 01609 * Success: ERROR_SUCCESS 01610 * Failure: Win32 error code. 01611 */ 01612 DWORD WINAPI SetupDecompressOrCopyFileW( PCWSTR source, PCWSTR target, PUINT type ) 01613 { 01614 UINT comp; 01615 DWORD ret = ERROR_INVALID_PARAMETER; 01616 01617 if (!source || !target) return ERROR_INVALID_PARAMETER; 01618 01619 if (!type) comp = detect_compression_type( source ); 01620 else comp = *type; 01621 01622 switch (comp) 01623 { 01624 case FILE_COMPRESSION_NONE: 01625 if (CopyFileW( source, target, FALSE )) ret = ERROR_SUCCESS; 01626 else ret = GetLastError(); 01627 break; 01628 case FILE_COMPRESSION_WINLZA: 01629 ret = decompress_file_lz( source, target ); 01630 break; 01631 case FILE_COMPRESSION_NTCAB: 01632 case FILE_COMPRESSION_MSZIP: 01633 ret = decompress_file_cab( source, target ); 01634 break; 01635 default: 01636 WARN("unknown compression type %d\n", comp); 01637 break; 01638 } 01639 01640 TRACE("%s -> %s %d\n", debugstr_w(source), debugstr_w(target), comp); 01641 return ret; 01642 } 01643 01644 /* 01645 * implemented (used by pSetupGuidFromString) 01646 */ 01647 static BOOL TrimGuidString(PCWSTR szString, LPWSTR szNewString) 01648 { 01649 WCHAR szBuffer[39]; 01650 INT Index; 01651 01652 if (wcslen(szString) == 38) 01653 { 01654 if ((szString[0] == L'{') && (szString[37] == L'}')) 01655 { 01656 for (Index = 0; Index < wcslen(szString); Index++) 01657 szBuffer[Index] = szString[Index + 1]; 01658 01659 szBuffer[36] = L'\0'; 01660 wcscpy(szNewString, szBuffer); 01661 return TRUE; 01662 } 01663 } 01664 szNewString[0] = L'\0'; 01665 return FALSE; 01666 } 01667 01668 /* 01669 * implemented 01670 */ 01671 DWORD 01672 WINAPI 01673 pSetupGuidFromString(PCWSTR pString, LPGUID lpGUID) 01674 { 01675 RPC_STATUS Status; 01676 WCHAR szBuffer[39]; 01677 01678 if (!TrimGuidString(pString, szBuffer)) 01679 { 01680 return RPC_S_INVALID_STRING_UUID; 01681 } 01682 01683 Status = UuidFromStringW(szBuffer, lpGUID); 01684 if (Status != RPC_S_OK) 01685 { 01686 return RPC_S_INVALID_STRING_UUID; 01687 } 01688 01689 return NO_ERROR; 01690 } 01691 01692 /* 01693 * implemented 01694 */ 01695 DWORD 01696 WINAPI 01697 pSetupStringFromGuid(LPGUID lpGUID, PWSTR pString, DWORD dwStringLen) 01698 { 01699 RPC_STATUS Status; 01700 RPC_WSTR rpcBuffer; 01701 WCHAR szBuffer[39]; 01702 01703 if (dwStringLen < 39) 01704 { 01705 return ERROR_INSUFFICIENT_BUFFER; 01706 } 01707 01708 Status = UuidToStringW(lpGUID, &rpcBuffer); 01709 if (Status != RPC_S_OK) 01710 { 01711 return Status; 01712 } 01713 01714 wcscpy(szBuffer, L"{"); 01715 wcscat(szBuffer, rpcBuffer); 01716 wcscat(szBuffer, L"}"); 01717 01718 wcscpy(pString, szBuffer); 01719 01720 RpcStringFreeW(&rpcBuffer); 01721 return NO_ERROR; 01722 } 01723 01724 /* 01725 * implemented 01726 */ 01727 BOOL 01728 WINAPI 01729 pSetupIsGuidNull(LPGUID lpGUID) 01730 { 01731 return IsEqualGUID(lpGUID, &GUID_NULL); 01732 } 01733 01734 /* 01735 * implemented 01736 */ 01737 BOOL 01738 WINAPI 01739 pSetupIsUserAdmin(VOID) 01740 { 01741 SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY}; 01742 BOOL bResult = FALSE; 01743 PSID lpSid; 01744 01745 if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID, 01746 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, 01747 &lpSid)) 01748 { 01749 return FALSE; 01750 } 01751 01752 if (!CheckTokenMembership(NULL, lpSid, &bResult)) 01753 { 01754 bResult = FALSE; 01755 } 01756 01757 FreeSid(lpSid); 01758 01759 return bResult; 01760 } 01761 01762 /*********************************************************************** 01763 * SetupInitializeFileLogW(SETUPAPI.@) 01764 */ 01765 HSPFILELOG WINAPI SetupInitializeFileLogW(LPCWSTR LogFileName, DWORD Flags) 01766 { 01767 struct FileLog * Log; 01768 HANDLE hLog; 01769 WCHAR Windir[MAX_PATH]; 01770 DWORD ret; 01771 01772 TRACE("%s, 0x%x\n",debugstr_w(LogFileName),Flags); 01773 01774 if (Flags & SPFILELOG_SYSTEMLOG) 01775 { 01776 if (!pSetupIsUserAdmin() && !(Flags & SPFILELOG_QUERYONLY)) 01777 { 01778 /* insufficient privileges */ 01779 SetLastError(ERROR_ACCESS_DENIED); 01780 return INVALID_HANDLE_VALUE; 01781 } 01782 01783 if (LogFileName || (Flags & SPFILELOG_FORCENEW)) 01784 { 01785 /* invalid parameter */ 01786 SetLastError(ERROR_INVALID_PARAMETER); 01787 return INVALID_HANDLE_VALUE; 01788 } 01789 01790 ret = GetSystemWindowsDirectoryW(Windir, MAX_PATH); 01791 if (!ret || ret >= MAX_PATH) 01792 { 01793 /* generic failure */ 01794 return INVALID_HANDLE_VALUE; 01795 } 01796 01797 /* append path */ 01798 wcscat(Windir, L"repair\\setup.log"); 01799 } 01800 else 01801 { 01802 if (!LogFileName) 01803 { 01804 /* invalid parameter */ 01805 SetLastError(ERROR_INVALID_PARAMETER); 01806 return INVALID_HANDLE_VALUE; 01807 } 01808 /* copy filename */ 01809 wcsncpy(Windir, LogFileName, MAX_PATH); 01810 } 01811 01812 if (FileExists(Windir, NULL)) 01813 { 01814 /* take ownership */ 01815 ret = TakeOwnershipOfFile(Windir); 01816 01817 if (ret != ERROR_SUCCESS) 01818 { 01819 /* failed */ 01820 SetLastError(ret); 01821 return INVALID_HANDLE_VALUE; 01822 } 01823 01824 if (!SetFileAttributesW(Windir, FILE_ATTRIBUTE_NORMAL)) 01825 { 01826 /* failed */ 01827 return INVALID_HANDLE_VALUE; 01828 } 01829 01830 if ((Flags & SPFILELOG_FORCENEW)) 01831 { 01832 if (!DeleteFileW(Windir)) 01833 { 01834 /* failed */ 01835 return INVALID_HANDLE_VALUE; 01836 } 01837 } 01838 } 01839 01840 /* open log file */ 01841 hLog = CreateFileW(Windir, 01842 (Flags & SPFILELOG_QUERYONLY) ? GENERIC_READ : GENERIC_WRITE, 01843 FILE_SHARE_READ | FILE_SHARE_WRITE, 01844 NULL, 01845 OPEN_ALWAYS, 01846 FILE_ATTRIBUTE_NORMAL, 01847 NULL); 01848 01849 if (hLog == INVALID_HANDLE_VALUE) 01850 { 01851 /* failed */ 01852 return INVALID_HANDLE_VALUE; 01853 } 01854 01855 /* close log handle */ 01856 CloseHandle(hLog); 01857 01858 /* allocate file log struct */ 01859 Log = HeapAlloc(GetProcessHeap(), 0, sizeof(struct FileLog)); 01860 if (!Log) 01861 { 01862 /* not enough memory */ 01863 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01864 return INVALID_HANDLE_VALUE; 01865 } 01866 01867 /* initialize log */ 01868 Log->LogName = HeapAlloc(GetProcessHeap(), 0, (wcslen(Windir)+1) * sizeof(WCHAR)); 01869 if (!Log->LogName) 01870 { 01871 /* not enough memory */ 01872 HeapFree(GetProcessHeap(), 0, Log); 01873 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01874 return INVALID_HANDLE_VALUE; 01875 } 01876 01877 wcscpy(Log->LogName, Windir); 01878 Log->ReadOnly = (Flags & SPFILELOG_QUERYONLY); 01879 Log->SystemLog = (Flags & SPFILELOG_SYSTEMLOG); 01880 01881 return (HSPFILELOG)Log; 01882 } 01883 01884 /*********************************************************************** 01885 * SetupInitializeFileLogA(SETUPAPI.@) 01886 */ 01887 HSPFILELOG WINAPI SetupInitializeFileLogA(LPCSTR LogFileName, DWORD Flags) 01888 { 01889 HSPFILELOG hLog; 01890 LPWSTR LogFileNameW = NULL; 01891 01892 TRACE("%s, 0x%x\n",debugstr_a(LogFileName),Flags); 01893 01894 if (LogFileName) 01895 { 01896 LogFileNameW = strdupAtoW(LogFileName); 01897 01898 if (!LogFileNameW) 01899 { 01900 /* not enough memory */ 01901 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01902 return INVALID_HANDLE_VALUE; 01903 } 01904 01905 hLog = SetupInitializeFileLogW(LogFileNameW, Flags); 01906 HeapFree(GetProcessHeap(), 0, LogFileNameW); 01907 } 01908 else 01909 { 01910 hLog = SetupInitializeFileLogW(NULL, Flags); 01911 } 01912 01913 return hLog; 01914 } 01915 01916 /*********************************************************************** 01917 * SetupTerminateFileLog(SETUPAPI.@) 01918 */ 01919 BOOL WINAPI SetupTerminateFileLog(HANDLE FileLogHandle) 01920 { 01921 struct FileLog * Log; 01922 01923 TRACE ("%p\n",FileLogHandle); 01924 01925 Log = (struct FileLog *)FileLogHandle; 01926 01927 /* free file log handle */ 01928 HeapFree(GetProcessHeap(), 0, Log->LogName); 01929 HeapFree(GetProcessHeap(), 0, Log); 01930 01931 SetLastError(ERROR_SUCCESS); 01932 01933 return TRUE; 01934 } Generated on Sat May 26 2012 04:15:47 for ReactOS by
1.7.6.1
|