Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenadvpack.c
Go to the documentation of this file.
00001 /* 00002 * Advpack main 00003 * 00004 * Copyright 2004 Huw D M Davies 00005 * Copyright 2005 Sami Aario 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 <stdarg.h> 00023 00024 #include "windef.h" 00025 #include "winbase.h" 00026 #include "winuser.h" 00027 #include "winreg.h" 00028 #include "winternl.h" 00029 #include "winnls.h" 00030 #include "setupapi.h" 00031 #include "advpub.h" 00032 #include "wine/unicode.h" 00033 #include "wine/debug.h" 00034 #include "advpack_private.h" 00035 00036 WINE_DEFAULT_DEBUG_CHANNEL(advpack); 00037 00038 typedef HRESULT (WINAPI *DLLREGISTER) (void); 00039 00040 #define MAX_FIELD_LENGTH 512 00041 #define PREFIX_LEN 5 00042 00043 /* registry path of the Installed Components key for per-user stubs */ 00044 static const WCHAR setup_key[] = { 00045 'S','O','F','T','W','A','R','E','\\', 00046 'M','i','c','r','o','s','o','f','t','\\', 00047 'A','c','t','i','v','e',' ','S','e','t','u','p','\\', 00048 'I','n','s','t','a','l','l','e','d',' ', 00049 'C','o','m','p','o','n','e','n','t','s',0 00050 }; 00051 00052 /* Strip single quotes from a token - note size includes NULL */ 00053 static void strip_quotes(WCHAR *buffer, DWORD *size) 00054 { 00055 if (buffer[0] == '\'' && (*size > 1) && buffer[*size-2]=='\'') 00056 { 00057 *size -= 2; 00058 buffer[*size] = 0x00; 00059 memmove(buffer, buffer + 1, *size * sizeof(WCHAR)); 00060 } 00061 } 00062 00063 /* parses the destination directory parameters from pszSection 00064 * the parameters are of the form: root,key,value,unknown,fallback 00065 * we first read the reg value root\\key\\value and if that fails, 00066 * use fallback as the destination directory 00067 */ 00068 static void get_dest_dir(HINF hInf, PCWSTR pszSection, PWSTR pszBuffer, DWORD dwSize) 00069 { 00070 INFCONTEXT context; 00071 WCHAR key[MAX_PATH + 2], value[MAX_PATH + 2]; 00072 WCHAR prefix[PREFIX_LEN + 2]; 00073 HKEY root, subkey = 0; 00074 DWORD size; 00075 00076 static const WCHAR hklm[] = {'H','K','L','M',0}; 00077 static const WCHAR hkcu[] = {'H','K','C','U',0}; 00078 00079 /* load the destination parameters */ 00080 SetupFindFirstLineW(hInf, pszSection, NULL, &context); 00081 SetupGetStringFieldW(&context, 1, prefix, PREFIX_LEN + 2, &size); 00082 strip_quotes(prefix, &size); 00083 SetupGetStringFieldW(&context, 2, key, MAX_PATH + 2, &size); 00084 strip_quotes(key, &size); 00085 SetupGetStringFieldW(&context, 3, value, MAX_PATH + 2, &size); 00086 strip_quotes(value, &size); 00087 00088 if (!lstrcmpW(prefix, hklm)) 00089 root = HKEY_LOCAL_MACHINE; 00090 else if (!lstrcmpW(prefix, hkcu)) 00091 root = HKEY_CURRENT_USER; 00092 else 00093 root = NULL; 00094 00095 size = dwSize * sizeof(WCHAR); 00096 00097 /* fallback to the default destination dir if reg fails */ 00098 if (RegOpenKeyW(root, key, &subkey) || 00099 RegQueryValueExW(subkey, value, NULL, NULL, (LPBYTE)pszBuffer, &size)) 00100 { 00101 SetupGetStringFieldW(&context, 5, pszBuffer, dwSize, &size); 00102 strip_quotes(pszBuffer, &size); 00103 } 00104 00105 if (subkey) RegCloseKey(subkey); 00106 } 00107 00108 /* loads the LDIDs specified in the install section of an INF */ 00109 void set_ldids(HINF hInf, LPCWSTR pszInstallSection, LPCWSTR pszWorkingDir) 00110 { 00111 WCHAR field[MAX_FIELD_LENGTH]; 00112 WCHAR line[MAX_FIELD_LENGTH]; 00113 WCHAR dest[MAX_PATH]; 00114 INFCONTEXT context; 00115 DWORD size; 00116 int ldid; 00117 00118 static const WCHAR source_dir[] = {'S','o','u','r','c','e','D','i','r',0}; 00119 00120 static const WCHAR custDestW[] = { 00121 'C','u','s','t','o','m','D','e','s','t','i','n','a','t','i','o','n',0 00122 }; 00123 00124 if (!SetupGetLineTextW(NULL, hInf, pszInstallSection, custDestW, 00125 field, MAX_FIELD_LENGTH, &size)) 00126 return; 00127 00128 if (!SetupFindFirstLineW(hInf, field, NULL, &context)) 00129 return; 00130 00131 do 00132 { 00133 LPWSTR value, ptr, key, key_copy = NULL; 00134 DWORD flags = 0; 00135 00136 SetupGetLineTextW(&context, NULL, NULL, NULL, 00137 line, MAX_FIELD_LENGTH, &size); 00138 00139 /* SetupGetLineTextW returns the value if there is only one key, but 00140 * returns the whole line if there is more than one key 00141 */ 00142 if (!(value = strchrW(line, '='))) 00143 { 00144 SetupGetStringFieldW(&context, 0, NULL, 0, &size); 00145 key = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); 00146 key_copy = key; 00147 SetupGetStringFieldW(&context, 0, key, size, &size); 00148 value = line; 00149 } 00150 else 00151 { 00152 key = line; 00153 *(value++) = '\0'; 00154 } 00155 00156 /* remove leading whitespace from the value */ 00157 while (*value == ' ') 00158 value++; 00159 00160 /* Extract the flags */ 00161 ptr = strchrW(value, ','); 00162 if (ptr) { 00163 *ptr = '\0'; 00164 flags = atolW(ptr+1); 00165 } 00166 00167 /* set dest to pszWorkingDir if key is SourceDir */ 00168 if (pszWorkingDir && !lstrcmpiW(value, source_dir)) 00169 lstrcpynW(dest, pszWorkingDir, MAX_PATH); 00170 else 00171 get_dest_dir(hInf, value, dest, MAX_PATH); 00172 00173 /* If prompting required, provide dialog to request path */ 00174 if (flags & 0x04) 00175 FIXME("Need to support changing paths - default will be used\n"); 00176 00177 /* set all ldids to dest */ 00178 while ((ptr = get_parameter(&key, ','))) 00179 { 00180 ldid = atolW(ptr); 00181 SetupSetDirectoryIdW(hInf, ldid, dest); 00182 } 00183 HeapFree(GetProcessHeap(), 0, key_copy); 00184 } while (SetupFindNextLine(&context, &context)); 00185 } 00186 00187 /*********************************************************************** 00188 * CloseINFEngine (ADVPACK.@) 00189 * 00190 * Closes a handle to an INF file opened with OpenINFEngine. 00191 * 00192 * PARAMS 00193 * hInf [I] Handle to the INF file to close. 00194 * 00195 * RETURNS 00196 * Success: S_OK. 00197 * Failure: E_FAIL. 00198 */ 00199 HRESULT WINAPI CloseINFEngine(HINF hInf) 00200 { 00201 TRACE("(%p)\n", hInf); 00202 00203 if (!hInf) 00204 return E_INVALIDARG; 00205 00206 SetupCloseInfFile(hInf); 00207 return S_OK; 00208 } 00209 00210 /*********************************************************************** 00211 * DllMain (ADVPACK.@) 00212 */ 00213 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 00214 { 00215 TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); 00216 00217 if (fdwReason == DLL_PROCESS_ATTACH) 00218 DisableThreadLibraryCalls(hinstDLL); 00219 00220 return TRUE; 00221 } 00222 00223 /*********************************************************************** 00224 * IsNTAdmin (ADVPACK.@) 00225 * 00226 * Checks if the user has admin privileges. 00227 * 00228 * PARAMS 00229 * reserved [I] Reserved. Must be 0. 00230 * pReserved [I] Reserved. Must be NULL. 00231 * 00232 * RETURNS 00233 * TRUE if user has admin rights, FALSE otherwise. 00234 */ 00235 BOOL WINAPI IsNTAdmin(DWORD reserved, LPDWORD pReserved) 00236 { 00237 SID_IDENTIFIER_AUTHORITY SidAuthority = {SECURITY_NT_AUTHORITY}; 00238 PTOKEN_GROUPS pTokenGroups; 00239 BOOL bSidFound = FALSE; 00240 DWORD dwSize, i; 00241 HANDLE hToken; 00242 PSID pSid; 00243 00244 TRACE("(%d, %p)\n", reserved, pReserved); 00245 00246 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) 00247 return FALSE; 00248 00249 if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize)) 00250 { 00251 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 00252 { 00253 CloseHandle(hToken); 00254 return FALSE; 00255 } 00256 } 00257 00258 pTokenGroups = HeapAlloc(GetProcessHeap(), 0, dwSize); 00259 if (!pTokenGroups) 00260 { 00261 CloseHandle(hToken); 00262 return FALSE; 00263 } 00264 00265 if (!GetTokenInformation(hToken, TokenGroups, pTokenGroups, dwSize, &dwSize)) 00266 { 00267 HeapFree(GetProcessHeap(), 0, pTokenGroups); 00268 CloseHandle(hToken); 00269 return FALSE; 00270 } 00271 00272 CloseHandle(hToken); 00273 00274 if (!AllocateAndInitializeSid(&SidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, 00275 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid)) 00276 { 00277 HeapFree(GetProcessHeap(), 0, pTokenGroups); 00278 return FALSE; 00279 } 00280 00281 for (i = 0; i < pTokenGroups->GroupCount; i++) 00282 { 00283 if (EqualSid(pSid, pTokenGroups->Groups[i].Sid)) 00284 { 00285 bSidFound = TRUE; 00286 break; 00287 } 00288 } 00289 00290 HeapFree(GetProcessHeap(), 0, pTokenGroups); 00291 FreeSid(pSid); 00292 00293 return bSidFound; 00294 } 00295 00296 /*********************************************************************** 00297 * NeedRebootInit (ADVPACK.@) 00298 * 00299 * Sets up conditions for reboot checking. 00300 * 00301 * RETURNS 00302 * Value required by NeedReboot. 00303 */ 00304 DWORD WINAPI NeedRebootInit(VOID) 00305 { 00306 FIXME("(VOID): stub\n"); 00307 return 0; 00308 } 00309 00310 /*********************************************************************** 00311 * NeedReboot (ADVPACK.@) 00312 * 00313 * Determines whether a reboot is required. 00314 * 00315 * PARAMS 00316 * dwRebootCheck [I] Value from NeedRebootInit. 00317 * 00318 * RETURNS 00319 * TRUE if a reboot is needed, FALSE otherwise. 00320 * 00321 * BUGS 00322 * Unimplemented. 00323 */ 00324 BOOL WINAPI NeedReboot(DWORD dwRebootCheck) 00325 { 00326 FIXME("(%d): stub\n", dwRebootCheck); 00327 return FALSE; 00328 } 00329 00330 /*********************************************************************** 00331 * OpenINFEngineA (ADVPACK.@) 00332 * 00333 * See OpenINFEngineW. 00334 */ 00335 HRESULT WINAPI OpenINFEngineA(LPCSTR pszInfFilename, LPCSTR pszInstallSection, 00336 DWORD dwFlags, HINF *phInf, PVOID pvReserved) 00337 { 00338 UNICODE_STRING filenameW, installW; 00339 HRESULT res; 00340 00341 TRACE("(%s, %s, %d, %p, %p)\n", debugstr_a(pszInfFilename), 00342 debugstr_a(pszInstallSection), dwFlags, phInf, pvReserved); 00343 00344 if (!pszInfFilename || !phInf) 00345 return E_INVALIDARG; 00346 00347 RtlCreateUnicodeStringFromAsciiz(&filenameW, pszInfFilename); 00348 RtlCreateUnicodeStringFromAsciiz(&installW, pszInstallSection); 00349 00350 res = OpenINFEngineW(filenameW.Buffer, installW.Buffer, 00351 dwFlags, phInf, pvReserved); 00352 00353 RtlFreeUnicodeString(&filenameW); 00354 RtlFreeUnicodeString(&installW); 00355 00356 return res; 00357 } 00358 00359 /*********************************************************************** 00360 * OpenINFEngineW (ADVPACK.@) 00361 * 00362 * Opens and returns a handle to an INF file to be used by 00363 * TranslateInfStringEx to continuously translate the INF file. 00364 * 00365 * PARAMS 00366 * pszInfFilename [I] Filename of the INF to open. 00367 * pszInstallSection [I] Name of the Install section in the INF. 00368 * dwFlags [I] See advpub.h. 00369 * phInf [O] Handle to the loaded INF file. 00370 * pvReserved [I] Reserved. Must be NULL. 00371 * 00372 * RETURNS 00373 * Success: S_OK. 00374 * Failure: E_FAIL. 00375 */ 00376 HRESULT WINAPI OpenINFEngineW(LPCWSTR pszInfFilename, LPCWSTR pszInstallSection, 00377 DWORD dwFlags, HINF *phInf, PVOID pvReserved) 00378 { 00379 TRACE("(%s, %s, %d, %p, %p)\n", debugstr_w(pszInfFilename), 00380 debugstr_w(pszInstallSection), dwFlags, phInf, pvReserved); 00381 00382 if (!pszInfFilename || !phInf) 00383 return E_INVALIDARG; 00384 00385 *phInf = SetupOpenInfFileW(pszInfFilename, NULL, INF_STYLE_WIN4, NULL); 00386 if (*phInf == INVALID_HANDLE_VALUE) 00387 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); 00388 00389 set_ldids(*phInf, pszInstallSection, NULL); 00390 00391 return S_OK; 00392 } 00393 00394 /*********************************************************************** 00395 * RebootCheckOnInstallA (ADVPACK.@) 00396 * 00397 * See RebootCheckOnInstallW. 00398 */ 00399 HRESULT WINAPI RebootCheckOnInstallA(HWND hWnd, LPCSTR pszINF, 00400 LPCSTR pszSec, DWORD dwReserved) 00401 { 00402 UNICODE_STRING infW, secW; 00403 HRESULT res; 00404 00405 TRACE("(%p, %s, %s, %d)\n", hWnd, debugstr_a(pszINF), 00406 debugstr_a(pszSec), dwReserved); 00407 00408 if (!pszINF || !pszSec) 00409 return E_INVALIDARG; 00410 00411 RtlCreateUnicodeStringFromAsciiz(&infW, pszINF); 00412 RtlCreateUnicodeStringFromAsciiz(&secW, pszSec); 00413 00414 res = RebootCheckOnInstallW(hWnd, infW.Buffer, secW.Buffer, dwReserved); 00415 00416 RtlFreeUnicodeString(&infW); 00417 RtlFreeUnicodeString(&secW); 00418 00419 return res; 00420 } 00421 00422 /*********************************************************************** 00423 * RebootCheckOnInstallW (ADVPACK.@) 00424 * 00425 * Checks if a reboot is required for an installed INF section. 00426 * 00427 * PARAMS 00428 * hWnd [I] Handle to the window used for messages. 00429 * pszINF [I] Filename of the INF file. 00430 * pszSec [I] INF section to check. 00431 * dwReserved [I] Reserved. Must be 0. 00432 * 00433 * RETURNS 00434 * Success: S_OK - Reboot is needed if the INF section is installed. 00435 * S_FALSE - Reboot is not needed. 00436 * Failure: HRESULT of GetLastError(). 00437 * 00438 * NOTES 00439 * if pszSec is NULL, RebootCheckOnInstall checks the DefaultInstall 00440 * or DefaultInstall.NT section. 00441 * 00442 * BUGS 00443 * Unimplemented. 00444 */ 00445 HRESULT WINAPI RebootCheckOnInstallW(HWND hWnd, LPCWSTR pszINF, 00446 LPCWSTR pszSec, DWORD dwReserved) 00447 { 00448 FIXME("(%p, %s, %s, %d): stub\n", hWnd, debugstr_w(pszINF), 00449 debugstr_w(pszSec), dwReserved); 00450 00451 return E_FAIL; 00452 } 00453 00454 /* registers the OCX if do_reg is TRUE, unregisters it otherwise */ 00455 HRESULT do_ocx_reg(HMODULE hocx, BOOL do_reg, const WCHAR *flags, const WCHAR *param) 00456 { 00457 DLLREGISTER reg_func; 00458 00459 if (do_reg) 00460 reg_func = (DLLREGISTER)GetProcAddress(hocx, "DllRegisterServer"); 00461 else 00462 reg_func = (DLLREGISTER)GetProcAddress(hocx, "DllUnregisterServer"); 00463 00464 if (!reg_func) 00465 return E_FAIL; 00466 00467 reg_func(); 00468 return S_OK; 00469 } 00470 00471 /*********************************************************************** 00472 * RegisterOCX (ADVPACK.@) 00473 * 00474 * Registers an OCX. 00475 * 00476 * PARAMS 00477 * hWnd [I] Handle to the window used for the display. 00478 * hInst [I] Instance of the process. 00479 * cmdline [I] Contains parameters in the order OCX,flags,param. 00480 * show [I] How the window should be shown. 00481 * 00482 * RETURNS 00483 * Success: S_OK. 00484 * Failure: E_FAIL. 00485 * 00486 * NOTES 00487 * OCX - Filename of the OCX to register. 00488 * flags - Controls the operation of RegisterOCX. 00489 * 'I' Call DllRegisterServer and DllInstall. 00490 * 'N' Only call DllInstall. 00491 * param - Command line passed to DllInstall. 00492 */ 00493 HRESULT WINAPI RegisterOCX(HWND hWnd, HINSTANCE hInst, LPCSTR cmdline, INT show) 00494 { 00495 LPWSTR ocx_filename, str_flags, param; 00496 LPWSTR cmdline_copy, cmdline_ptr; 00497 UNICODE_STRING cmdlineW; 00498 HRESULT hr = E_FAIL; 00499 HMODULE hm = NULL; 00500 DWORD size; 00501 00502 TRACE("(%s)\n", debugstr_a(cmdline)); 00503 00504 RtlCreateUnicodeStringFromAsciiz(&cmdlineW, cmdline); 00505 00506 size = (lstrlenW(cmdlineW.Buffer) + 1) * sizeof(WCHAR); 00507 cmdline_copy = HeapAlloc(GetProcessHeap(), 0, size); 00508 cmdline_ptr = cmdline_copy; 00509 lstrcpyW(cmdline_copy, cmdlineW.Buffer); 00510 00511 ocx_filename = get_parameter(&cmdline_ptr, ','); 00512 if (!ocx_filename || !*ocx_filename) 00513 goto done; 00514 00515 str_flags = get_parameter(&cmdline_ptr, ','); 00516 param = get_parameter(&cmdline_ptr, ','); 00517 00518 hm = LoadLibraryExW(ocx_filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 00519 if (!hm) 00520 goto done; 00521 00522 hr = do_ocx_reg(hm, TRUE, str_flags, param); 00523 00524 done: 00525 FreeLibrary(hm); 00526 HeapFree(GetProcessHeap(), 0, cmdline_copy); 00527 RtlFreeUnicodeString(&cmdlineW); 00528 00529 return hr; 00530 } 00531 00532 /*********************************************************************** 00533 * SetPerUserSecValuesA (ADVPACK.@) 00534 * 00535 * See SetPerUserSecValuesW. 00536 */ 00537 HRESULT WINAPI SetPerUserSecValuesA(PERUSERSECTIONA* pPerUser) 00538 { 00539 PERUSERSECTIONW perUserW; 00540 00541 TRACE("(%p)\n", pPerUser); 00542 00543 if (!pPerUser) 00544 return E_INVALIDARG; 00545 00546 MultiByteToWideChar(CP_ACP, 0, pPerUser->szGUID, -1, perUserW.szGUID, 00547 sizeof(perUserW.szGUID) / sizeof(WCHAR)); 00548 MultiByteToWideChar(CP_ACP, 0, pPerUser->szDispName, -1, perUserW.szDispName, 00549 sizeof(perUserW.szDispName) / sizeof(WCHAR)); 00550 MultiByteToWideChar(CP_ACP, 0, pPerUser->szLocale, -1, perUserW.szLocale, 00551 sizeof(perUserW.szLocale) / sizeof(WCHAR)); 00552 MultiByteToWideChar(CP_ACP, 0, pPerUser->szStub, -1, perUserW.szStub, 00553 sizeof(perUserW.szStub) / sizeof(WCHAR)); 00554 MultiByteToWideChar(CP_ACP, 0, pPerUser->szVersion, -1, perUserW.szVersion, 00555 sizeof(perUserW.szVersion) / sizeof(WCHAR)); 00556 MultiByteToWideChar(CP_ACP, 0, pPerUser->szCompID, -1, perUserW.szCompID, 00557 sizeof(perUserW.szCompID) / sizeof(WCHAR)); 00558 perUserW.dwIsInstalled = pPerUser->dwIsInstalled; 00559 perUserW.bRollback = pPerUser->bRollback; 00560 00561 return SetPerUserSecValuesW(&perUserW); 00562 } 00563 00564 /*********************************************************************** 00565 * SetPerUserSecValuesW (ADVPACK.@) 00566 * 00567 * Prepares the per-user stub values under IsInstalled\{GUID} that 00568 * control the per-user installation. 00569 * 00570 * PARAMS 00571 * pPerUser [I] Per-user stub values. 00572 * 00573 * RETURNS 00574 * Success: S_OK. 00575 * Failure: E_FAIL. 00576 */ 00577 HRESULT WINAPI SetPerUserSecValuesW(PERUSERSECTIONW* pPerUser) 00578 { 00579 HKEY setup, guid; 00580 00581 static const WCHAR stub_path[] = {'S','t','u','b','P','a','t','h',0}; 00582 static const WCHAR version[] = {'V','e','r','s','i','o','n',0}; 00583 static const WCHAR locale[] = {'L','o','c','a','l','e',0}; 00584 static const WCHAR compid[] = {'C','o','m','p','o','n','e','n','t','I','D',0}; 00585 static const WCHAR isinstalled[] = {'I','s','I','n','s','t','a','l','l','e','d',0}; 00586 00587 TRACE("(%p)\n", pPerUser); 00588 00589 if (!pPerUser || !*pPerUser->szGUID) 00590 return S_OK; 00591 00592 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, setup_key, 0, NULL, 0, KEY_WRITE, 00593 NULL, &setup, NULL)) 00594 { 00595 return E_FAIL; 00596 } 00597 00598 if (RegCreateKeyExW(setup, pPerUser->szGUID, 0, NULL, 0, KEY_ALL_ACCESS, 00599 NULL, &guid, NULL)) 00600 { 00601 RegCloseKey(setup); 00602 return E_FAIL; 00603 } 00604 00605 if (*pPerUser->szStub) 00606 { 00607 RegSetValueExW(guid, stub_path, 0, REG_SZ, (LPBYTE)pPerUser->szStub, 00608 (lstrlenW(pPerUser->szStub) + 1) * sizeof(WCHAR)); 00609 } 00610 00611 if (*pPerUser->szVersion) 00612 { 00613 RegSetValueExW(guid, version, 0, REG_SZ, (LPBYTE)pPerUser->szVersion, 00614 (lstrlenW(pPerUser->szVersion) + 1) * sizeof(WCHAR)); 00615 } 00616 00617 if (*pPerUser->szLocale) 00618 { 00619 RegSetValueExW(guid, locale, 0, REG_SZ, (LPBYTE)pPerUser->szLocale, 00620 (lstrlenW(pPerUser->szLocale) + 1) * sizeof(WCHAR)); 00621 } 00622 00623 if (*pPerUser->szCompID) 00624 { 00625 RegSetValueExW(guid, compid, 0, REG_SZ, (LPBYTE)pPerUser->szCompID, 00626 (lstrlenW(pPerUser->szCompID) + 1) * sizeof(WCHAR)); 00627 } 00628 00629 if (*pPerUser->szDispName) 00630 { 00631 RegSetValueExW(guid, NULL, 0, REG_SZ, (LPBYTE)pPerUser->szDispName, 00632 (lstrlenW(pPerUser->szDispName) + 1) * sizeof(WCHAR)); 00633 } 00634 00635 RegSetValueExW(guid, isinstalled, 0, REG_DWORD, 00636 (LPBYTE)&pPerUser->dwIsInstalled, sizeof(DWORD)); 00637 00638 RegCloseKey(guid); 00639 RegCloseKey(setup); 00640 00641 return S_OK; 00642 } 00643 00644 /*********************************************************************** 00645 * TranslateInfStringA (ADVPACK.@) 00646 * 00647 * See TranslateInfStringW. 00648 */ 00649 HRESULT WINAPI TranslateInfStringA(LPCSTR pszInfFilename, LPCSTR pszInstallSection, 00650 LPCSTR pszTranslateSection, LPCSTR pszTranslateKey, LPSTR pszBuffer, 00651 DWORD dwBufferSize, PDWORD pdwRequiredSize, PVOID pvReserved) 00652 { 00653 UNICODE_STRING filenameW, installW; 00654 UNICODE_STRING translateW, keyW; 00655 LPWSTR bufferW; 00656 HRESULT res; 00657 DWORD len = 0; 00658 00659 TRACE("(%s, %s, %s, %s, %p, %d, %p, %p)\n", 00660 debugstr_a(pszInfFilename), debugstr_a(pszInstallSection), 00661 debugstr_a(pszTranslateSection), debugstr_a(pszTranslateKey), 00662 pszBuffer, dwBufferSize,pdwRequiredSize, pvReserved); 00663 00664 if (!pszInfFilename || !pszTranslateSection || 00665 !pszTranslateKey || !pdwRequiredSize) 00666 return E_INVALIDARG; 00667 00668 RtlCreateUnicodeStringFromAsciiz(&filenameW, pszInfFilename); 00669 RtlCreateUnicodeStringFromAsciiz(&installW, pszInstallSection); 00670 RtlCreateUnicodeStringFromAsciiz(&translateW, pszTranslateSection); 00671 RtlCreateUnicodeStringFromAsciiz(&keyW, pszTranslateKey); 00672 00673 res = TranslateInfStringW(filenameW.Buffer, installW.Buffer, 00674 translateW.Buffer, keyW.Buffer, NULL, 00675 dwBufferSize, &len, NULL); 00676 00677 if (res == S_OK) 00678 { 00679 bufferW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00680 00681 res = TranslateInfStringW(filenameW.Buffer, installW.Buffer, 00682 translateW.Buffer, keyW.Buffer, bufferW, 00683 len, &len, NULL); 00684 if (res == S_OK) 00685 { 00686 *pdwRequiredSize = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, 00687 NULL, 0, NULL, NULL); 00688 00689 if (dwBufferSize >= *pdwRequiredSize) 00690 { 00691 WideCharToMultiByte(CP_ACP, 0, bufferW, -1, pszBuffer, 00692 dwBufferSize, NULL, NULL); 00693 } 00694 else 00695 res = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00696 } 00697 00698 HeapFree(GetProcessHeap(), 0, bufferW); 00699 } 00700 00701 RtlFreeUnicodeString(&filenameW); 00702 RtlFreeUnicodeString(&installW); 00703 RtlFreeUnicodeString(&translateW); 00704 RtlFreeUnicodeString(&keyW); 00705 00706 return res; 00707 } 00708 00709 /*********************************************************************** 00710 * TranslateInfStringW (ADVPACK.@) 00711 * 00712 * Translates the value of a specified key in an inf file into the 00713 * current locale by expanding string macros. 00714 * 00715 * PARAMS 00716 * pszInfFilename [I] Filename of the inf file. 00717 * pszInstallSection [I] 00718 * pszTranslateSection [I] Inf section where the key exists. 00719 * pszTranslateKey [I] Key to translate. 00720 * pszBuffer [O] Contains the translated string on exit. 00721 * dwBufferSize [I] Size on input of pszBuffer. 00722 * pdwRequiredSize [O] Length of the translated key. 00723 * pvReserved [I] Reserved, must be NULL. 00724 * 00725 * RETURNS 00726 * Success: S_OK. 00727 * Failure: An hresult error code. 00728 */ 00729 HRESULT WINAPI TranslateInfStringW(LPCWSTR pszInfFilename, LPCWSTR pszInstallSection, 00730 LPCWSTR pszTranslateSection, LPCWSTR pszTranslateKey, LPWSTR pszBuffer, 00731 DWORD dwBufferSize, PDWORD pdwRequiredSize, PVOID pvReserved) 00732 { 00733 HINF hInf; 00734 HRESULT hret = S_OK; 00735 00736 TRACE("(%s, %s, %s, %s, %p, %d, %p, %p)\n", 00737 debugstr_w(pszInfFilename), debugstr_w(pszInstallSection), 00738 debugstr_w(pszTranslateSection), debugstr_w(pszTranslateKey), 00739 pszBuffer, dwBufferSize,pdwRequiredSize, pvReserved); 00740 00741 if (!pszInfFilename || !pszTranslateSection || 00742 !pszTranslateKey || !pdwRequiredSize) 00743 return E_INVALIDARG; 00744 00745 hInf = SetupOpenInfFileW(pszInfFilename, NULL, INF_STYLE_WIN4, NULL); 00746 if (hInf == INVALID_HANDLE_VALUE) 00747 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); 00748 00749 set_ldids(hInf, pszInstallSection, NULL); 00750 00751 if (!SetupGetLineTextW(NULL, hInf, pszTranslateSection, pszTranslateKey, 00752 pszBuffer, dwBufferSize, pdwRequiredSize)) 00753 { 00754 if (dwBufferSize < *pdwRequiredSize) 00755 hret = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00756 else 00757 hret = SPAPI_E_LINE_NOT_FOUND; 00758 } 00759 00760 SetupCloseInfFile(hInf); 00761 return hret; 00762 } 00763 00764 /*********************************************************************** 00765 * TranslateInfStringExA (ADVPACK.@) 00766 * 00767 * See TranslateInfStringExW. 00768 */ 00769 HRESULT WINAPI TranslateInfStringExA(HINF hInf, LPCSTR pszInfFilename, 00770 LPCSTR pszTranslateSection, LPCSTR pszTranslateKey, 00771 LPSTR pszBuffer, DWORD dwBufferSize, 00772 PDWORD pdwRequiredSize, PVOID pvReserved) 00773 { 00774 UNICODE_STRING filenameW, sectionW, keyW; 00775 LPWSTR bufferW; 00776 HRESULT res; 00777 DWORD len = 0; 00778 00779 TRACE("(%p, %s, %s, %s, %s, %d, %p, %p)\n", hInf, debugstr_a(pszInfFilename), 00780 debugstr_a(pszTranslateSection), debugstr_a(pszTranslateKey), 00781 debugstr_a(pszBuffer), dwBufferSize, pdwRequiredSize, pvReserved); 00782 00783 if (!pszInfFilename || !pszTranslateSection || 00784 !pszTranslateKey || !pdwRequiredSize) 00785 return E_INVALIDARG; 00786 00787 RtlCreateUnicodeStringFromAsciiz(&filenameW, pszInfFilename); 00788 RtlCreateUnicodeStringFromAsciiz(§ionW, pszTranslateSection); 00789 RtlCreateUnicodeStringFromAsciiz(&keyW, pszTranslateKey); 00790 00791 res = TranslateInfStringExW(hInf, filenameW.Buffer, sectionW.Buffer, 00792 keyW.Buffer, NULL, 0, &len, NULL); 00793 00794 if (res == S_OK) 00795 { 00796 bufferW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00797 00798 res = TranslateInfStringExW(hInf, filenameW.Buffer, sectionW.Buffer, 00799 keyW.Buffer, bufferW, len, &len, NULL); 00800 00801 if (res == S_OK) 00802 { 00803 *pdwRequiredSize = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, 00804 NULL, 0, NULL, NULL); 00805 00806 if (dwBufferSize >= *pdwRequiredSize) 00807 { 00808 WideCharToMultiByte(CP_ACP, 0, bufferW, -1, pszBuffer, 00809 dwBufferSize, NULL, NULL); 00810 } 00811 else 00812 res = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00813 } 00814 00815 HeapFree(GetProcessHeap(), 0, bufferW); 00816 } 00817 00818 RtlFreeUnicodeString(&filenameW); 00819 RtlFreeUnicodeString(§ionW); 00820 RtlFreeUnicodeString(&keyW); 00821 00822 return res; 00823 } 00824 00825 /*********************************************************************** 00826 * TranslateInfStringExW (ADVPACK.@) 00827 * 00828 * Using a handle to an INF file opened with OpenINFEngine, translates 00829 * the value of a specified key in an inf file into the current locale 00830 * by expanding string macros. 00831 * 00832 * PARAMS 00833 * hInf [I] Handle to the INF file. 00834 * pszInfFilename [I] Filename of the INF file. 00835 * pszTranslateSection [I] Inf section where the key exists. 00836 * pszTranslateKey [I] Key to translate. 00837 * pszBuffer [O] Contains the translated string on exit. 00838 * dwBufferSize [I] Size on input of pszBuffer. 00839 * pdwRequiredSize [O] Length of the translated key. 00840 * pvReserved [I] Reserved. Must be NULL. 00841 * 00842 * RETURNS 00843 * Success: S_OK. 00844 * Failure: E_FAIL. 00845 * 00846 * NOTES 00847 * To use TranslateInfStringEx to translate an INF file continuously, 00848 * open the INF file with OpenINFEngine, call TranslateInfStringEx as 00849 * many times as needed, then release the handle with CloseINFEngine. 00850 * When translating more than one keys, this method is more efficient 00851 * than calling TranslateInfString, because the INF file is only 00852 * opened once. 00853 */ 00854 HRESULT WINAPI TranslateInfStringExW(HINF hInf, LPCWSTR pszInfFilename, 00855 LPCWSTR pszTranslateSection, LPCWSTR pszTranslateKey, 00856 LPWSTR pszBuffer, DWORD dwBufferSize, 00857 PDWORD pdwRequiredSize, PVOID pvReserved) 00858 { 00859 TRACE("(%p, %s, %s, %s, %s, %d, %p, %p)\n", hInf, debugstr_w(pszInfFilename), 00860 debugstr_w(pszTranslateSection), debugstr_w(pszTranslateKey), 00861 debugstr_w(pszBuffer), dwBufferSize, pdwRequiredSize, pvReserved); 00862 00863 if (!hInf || !pszInfFilename || !pszTranslateSection || !pszTranslateKey) 00864 return E_INVALIDARG; 00865 00866 if (!SetupGetLineTextW(NULL, hInf, pszTranslateSection, pszTranslateKey, 00867 pszBuffer, dwBufferSize, pdwRequiredSize)) 00868 { 00869 if (dwBufferSize < *pdwRequiredSize) 00870 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); 00871 00872 return SPAPI_E_LINE_NOT_FOUND; 00873 } 00874 00875 return S_OK; 00876 } 00877 00878 /*********************************************************************** 00879 * UserInstStubWrapperA (ADVPACK.@) 00880 * 00881 * See UserInstStubWrapperW. 00882 */ 00883 HRESULT WINAPI UserInstStubWrapperA(HWND hWnd, HINSTANCE hInstance, 00884 LPSTR pszParms, INT nShow) 00885 { 00886 UNICODE_STRING parmsW; 00887 HRESULT res; 00888 00889 TRACE("(%p, %p, %s, %i)\n", hWnd, hInstance, debugstr_a(pszParms), nShow); 00890 00891 if (!pszParms) 00892 return E_INVALIDARG; 00893 00894 RtlCreateUnicodeStringFromAsciiz(&parmsW, pszParms); 00895 00896 res = UserInstStubWrapperW(hWnd, hInstance, parmsW.Buffer, nShow); 00897 00898 RtlFreeUnicodeString(&parmsW); 00899 00900 return res; 00901 } 00902 00903 /*********************************************************************** 00904 * UserInstStubWrapperW (ADVPACK.@) 00905 * 00906 * Launches the user stub wrapper specified by the RealStubPath 00907 * registry value under Installed Components\szParms. 00908 * 00909 * PARAMS 00910 * hWnd [I] Handle to the window used for the display. 00911 * hInstance [I] Instance of the process. 00912 * szParms [I] The GUID of the installation. 00913 * show [I] How the window should be shown. 00914 * 00915 * RETURNS 00916 * Success: S_OK. 00917 * Failure: E_FAIL. 00918 * 00919 * TODO 00920 * If the type of the StubRealPath value is REG_EXPAND_SZ, then 00921 * we should call ExpandEnvironmentStrings on the value and 00922 * launch the result. 00923 */ 00924 HRESULT WINAPI UserInstStubWrapperW(HWND hWnd, HINSTANCE hInstance, 00925 LPWSTR pszParms, INT nShow) 00926 { 00927 HKEY setup, guid; 00928 WCHAR stub[MAX_PATH]; 00929 DWORD size = MAX_PATH; 00930 HRESULT hr = S_OK; 00931 BOOL res; 00932 00933 static const WCHAR real_stub_path[] = { 00934 'R','e','a','l','S','t','u','b','P','a','t','h',0 00935 }; 00936 00937 TRACE("(%p, %p, %s, %i)\n", hWnd, hInstance, debugstr_w(pszParms), nShow); 00938 00939 if (!pszParms || !*pszParms) 00940 return E_INVALIDARG; 00941 00942 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, setup_key, 0, KEY_READ, &setup)) 00943 { 00944 return E_FAIL; 00945 } 00946 00947 if (RegOpenKeyExW(setup, pszParms, 0, KEY_READ, &guid)) 00948 { 00949 RegCloseKey(setup); 00950 return E_FAIL; 00951 } 00952 00953 res = RegQueryValueExW(guid, real_stub_path, NULL, NULL, (LPBYTE)stub, &size); 00954 if (res || !*stub) 00955 goto done; 00956 00957 /* launch the user stub wrapper */ 00958 hr = launch_exe(stub, NULL, NULL); 00959 00960 done: 00961 RegCloseKey(setup); 00962 RegCloseKey(guid); 00963 00964 return hr; 00965 } 00966 00967 /*********************************************************************** 00968 * UserUnInstStubWrapperA (ADVPACK.@) 00969 * 00970 * See UserUnInstStubWrapperW. 00971 */ 00972 HRESULT WINAPI UserUnInstStubWrapperA(HWND hWnd, HINSTANCE hInstance, 00973 LPSTR pszParms, INT nShow) 00974 { 00975 UNICODE_STRING parmsW; 00976 HRESULT res; 00977 00978 TRACE("(%p, %p, %s, %i)\n", hWnd, hInstance, debugstr_a(pszParms), nShow); 00979 00980 if (!pszParms) 00981 return E_INVALIDARG; 00982 00983 RtlCreateUnicodeStringFromAsciiz(&parmsW, pszParms); 00984 00985 res = UserUnInstStubWrapperW(hWnd, hInstance, parmsW.Buffer, nShow); 00986 00987 RtlFreeUnicodeString(&parmsW); 00988 00989 return res; 00990 } 00991 00992 /*********************************************************************** 00993 * UserUnInstStubWrapperW (ADVPACK.@) 00994 */ 00995 HRESULT WINAPI UserUnInstStubWrapperW(HWND hWnd, HINSTANCE hInstance, 00996 LPWSTR pszParms, INT nShow) 00997 { 00998 FIXME("(%p, %p, %s, %i): stub\n", hWnd, hInstance, debugstr_w(pszParms), nShow); 00999 01000 return E_FAIL; 01001 } Generated on Sun May 27 2012 04:22:46 for ReactOS by
1.7.6.1
|