ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

advpack.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(&sectionW, 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(&sectionW);
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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.