4 * Copyright 2004 Huw D M Davies
5 * Copyright 2005 Sami Aario
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "wine/unicode.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(advpack);
37 typedef HRESULT (WINAPI *DLLREGISTER) (void);
39 /***********************************************************************
40 * AdvInstallFile (ADVPACK.@)
42 * Copies a file from the source to a destination.
45 * hwnd [I] Handle to the window used for messages.
46 * lpszSourceDir [I] Source directory.
47 * lpszSourceFile [I] Source filename.
48 * lpszDestDir [I] Destination directory.
49 * lpszDestFile [I] Optional destination filename.
50 * dwFlags [I] See advpub.h.
51 * dwReserved [I] Reserved. Must be 0.
58 * If lpszDestFile is NULL, the destination filename is the same as
64 HRESULT WINAPI AdvInstallFile(HWND hwnd, LPCSTR lpszSourceDir, LPCSTR lpszSourceFile,
65 LPCSTR lpszDestDir, LPCSTR lpszDestFile,
66 DWORD dwFlags, DWORD dwReserved)
68 FIXME("(%p,%p,%p,%p,%p,%ld,%ld) stub\n", hwnd, debugstr_a(lpszSourceDir),
69 debugstr_a(lpszSourceFile), debugstr_a(lpszDestDir),
70 debugstr_a(lpszDestFile), dwFlags, dwReserved);
74 /***********************************************************************
77 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
79 TRACE("(%p, %ld, %p)\n",hinstDLL, fdwReason, lpvReserved);
81 if (fdwReason == DLL_PROCESS_ATTACH)
82 DisableThreadLibraryCalls(hinstDLL);
87 /***********************************************************************
88 * RunSetupCommand (ADVPACK.@)
90 * Executes an install section in an INF file or a program.
93 * hWnd [I] Handle to parent window, NULL for quiet mode
94 * szCmdName [I] Inf or EXE filename to execute
95 * szInfSection [I] Inf section to install, NULL for DefaultInstall
96 * szDir [I] Path to extracted files
97 * szTitle [I] Title of all dialogs
98 * phEXE [O] Handle of EXE to wait for
99 * dwFlags [I] Flags; see include/advpub.h
100 * pvReserved [I] Reserved
104 * S_ASYNCHRONOUS OK, required to wait on phEXE
105 * ERROR_SUCCESS_REBOOT_REQUIRED Reboot required
106 * E_INVALIDARG Invalid argument given
107 * HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION)
108 * Not supported on this Windows version
109 * E_UNEXPECTED Unexpected error
110 * HRESULT_FROM_WIN32(GetLastError()) Some other error
115 HRESULT WINAPI RunSetupCommand( HWND hWnd, LPCSTR szCmdName,
116 LPCSTR szInfSection, LPCSTR szDir,
117 LPCSTR lpszTitle, HANDLE *phEXE,
118 DWORD dwFlags, LPVOID pvReserved )
120 FIXME("(%p, %s, %s, %s, %s, %p, 0x%08lx, %p): stub\n",
121 hWnd, debugstr_a(szCmdName), debugstr_a(szInfSection),
122 debugstr_a(szDir), debugstr_a(lpszTitle),
123 phEXE, dwFlags, pvReserved);
127 /***********************************************************************
128 * LaunchINFSection (ADVPACK.@)
130 INT WINAPI LaunchINFSection( HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show )
132 FIXME("(%p %p %s %d): stub\n", hWnd, hInst, debugstr_a(cmdline), show );
136 /***********************************************************************
137 * LaunchINFSectionEx (ADVPACK.@)
139 HRESULT WINAPI LaunchINFSectionEx( HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show )
141 FIXME("(%p %p %s %d): stub\n", hWnd, hInst, debugstr_a(cmdline), show );
145 /* this structure very closely resembles parameters of RunSetupCommand() */
153 } SETUPCOMMAND_PARAMS;
155 /***********************************************************************
156 * DoInfInstall (ADVPACK.@)
158 BOOL WINAPI DoInfInstall(const SETUPCOMMAND_PARAMS *setup)
162 void *callback_context;
164 TRACE("%p %s %s %s %s\n", setup->hwnd, debugstr_a(setup->title),
165 debugstr_a(setup->inf_name), debugstr_a(setup->dir),
166 debugstr_a(setup->section_name));
168 hinf = SetupOpenInfFileA(setup->inf_name, NULL, INF_STYLE_WIN4, NULL);
169 if (hinf == INVALID_HANDLE_VALUE) return FALSE;
171 callback_context = SetupInitDefaultQueueCallback(setup->hwnd);
173 ret = SetupInstallFromInfSectionA(NULL, hinf, setup->section_name, SPINST_ALL,
174 NULL, NULL, 0, SetupDefaultQueueCallbackA,
175 callback_context, NULL, NULL);
176 SetupTermDefaultQueueCallback(callback_context);
177 SetupCloseInfFile(hinf);
182 /***********************************************************************
183 * IsNTAdmin (ADVPACK.@)
185 BOOL WINAPI IsNTAdmin( DWORD reserved, LPDWORD pReserved )
187 FIXME("(0x%08lx, %p): stub\n", reserved, pReserved);
191 /***********************************************************************
192 * NeedRebootInit (ADVPACK.@)
194 DWORD WINAPI NeedRebootInit(VOID)
200 /***********************************************************************
201 * NeedReboot (ADVPACK.@)
203 BOOL WINAPI NeedReboot(DWORD dwRebootCheck)
205 FIXME("(0x%08lx): stub\n", dwRebootCheck);
209 /***********************************************************************
210 * GetVersionFromFile (ADVPACK.@)
212 HRESULT WINAPI GetVersionFromFile( LPSTR Filename, LPDWORD MajorVer,
213 LPDWORD MinorVer, BOOL Version )
215 TRACE("(%s, %p, %p, %d)\n", Filename, MajorVer, MinorVer, Version);
216 return GetVersionFromFileEx(Filename, MajorVer, MinorVer, Version);
219 /* data for GetVersionFromFileEx */
220 typedef struct tagLANGANDCODEPAGE
226 /***********************************************************************
227 * GetVersionFromFileEx (ADVPACK.@)
229 HRESULT WINAPI GetVersionFromFileEx( LPSTR lpszFilename, LPDWORD pdwMSVer,
230 LPDWORD pdwLSVer, BOOL bVersion )
232 VS_FIXEDFILEINFO *pFixedVersionInfo;
233 LANGANDCODEPAGE *pLangAndCodePage;
234 DWORD dwHandle, dwInfoSize;
235 CHAR szWinDir[MAX_PATH];
236 CHAR szFile[MAX_PATH];
237 LPVOID pVersionInfo = NULL;
238 BOOL bFileCopied = FALSE;
241 TRACE("(%s, %p, %p, %d)\n", lpszFilename, pdwMSVer, pdwLSVer, bVersion);
246 lstrcpynA(szFile, lpszFilename, MAX_PATH);
248 dwInfoSize = GetFileVersionInfoSizeA(szFile, &dwHandle);
251 /* check that the file exists */
252 if (GetFileAttributesA(szFile) == INVALID_FILE_ATTRIBUTES)
255 /* file exists, but won't be found by GetFileVersionInfoSize,
256 * so copy it to the temp dir where it will be found.
258 GetWindowsDirectoryA(szWinDir, MAX_PATH);
259 GetTempFileNameA(szWinDir, NULL, 0, szFile);
260 CopyFileA(lpszFilename, szFile, FALSE);
263 dwInfoSize = GetFileVersionInfoSizeA(szFile, &dwHandle);
268 pVersionInfo = HeapAlloc(GetProcessHeap(), 0, dwInfoSize);
272 if (!GetFileVersionInfoA(szFile, dwHandle, dwInfoSize, pVersionInfo))
277 if (!VerQueryValueA(pVersionInfo, "\\",
278 (LPVOID *)&pFixedVersionInfo, &uValueLen))
284 *pdwMSVer = pFixedVersionInfo->dwFileVersionMS;
285 *pdwLSVer = pFixedVersionInfo->dwFileVersionLS;
289 if (!VerQueryValueA(pVersionInfo, "\\VarFileInfo\\Translation",
290 (LPVOID *)&pLangAndCodePage, &uValueLen))
296 *pdwMSVer = pLangAndCodePage->wLanguage;
297 *pdwLSVer = pLangAndCodePage->wCodePage;
301 HeapFree(GetProcessHeap(), 0, pVersionInfo);
309 /***********************************************************************
310 * RegisterOCX (ADVPACK.@)
312 void WINAPI RegisterOCX( HWND hWnd, HINSTANCE hInst, LPCSTR cmdline, INT show )
314 WCHAR wszBuff[MAX_PATH];
317 DLLREGISTER pfnRegister;
320 TRACE("(%s)\n", cmdline);
322 MultiByteToWideChar(CP_ACP, 0, cmdline, strlen(cmdline), wszBuff, MAX_PATH);
323 if ((pwcComma = strchrW( wszBuff, ',' ))) *pwcComma = 0;
325 TRACE("Parsed DLL name (%s)\n", debugstr_w(wszBuff));
327 hm = LoadLibraryExW(wszBuff, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
330 ERR("Couldn't load DLL: %s\n", debugstr_w(wszBuff));
334 pfnRegister = (DLLREGISTER)GetProcAddress(hm, "DllRegisterServer");
335 if (pfnRegister == NULL)
337 ERR("DllRegisterServer entry point not found\n");
344 ERR("DllRegisterServer entry point returned %08lx\n", hr);
348 TRACE("Successfully registered OCX\n");
353 static HRESULT DELNODE_recurse_dirtree(LPSTR fname, DWORD flags)
355 DWORD fattrs = GetFileAttributesA(fname);
356 HRESULT ret = E_FAIL;
358 if (fattrs & FILE_ATTRIBUTE_DIRECTORY)
361 WIN32_FIND_DATAA w32fd;
363 int fname_len = lstrlenA(fname);
365 /* Generate a path with wildcard suitable for iterating */
366 if (CharPrevA(fname, fname + fname_len) != "\\")
368 lstrcpyA(fname + fname_len, "\\");
371 lstrcpyA(fname + fname_len, "*");
373 if ((hFindFile = FindFirstFileA(fname, &w32fd)) != INVALID_HANDLE_VALUE)
375 /* Iterate through the files in the directory */
376 for (done = FALSE; !done; done = !FindNextFileA(hFindFile, &w32fd))
378 TRACE("%s\n", w32fd.cFileName);
379 if (lstrcmpA(".", w32fd.cFileName) != 0 &&
380 lstrcmpA("..", w32fd.cFileName) != 0)
382 lstrcpyA(fname + fname_len, w32fd.cFileName);
383 if (DELNODE_recurse_dirtree(fname, flags) != S_OK)
389 FindClose(hFindFile);
392 /* We're done with this directory, so restore the old path without wildcard */
393 *(fname + fname_len) = '\0';
397 TRACE("%s: directory\n", fname);
398 if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && RemoveDirectoryA(fname))
406 TRACE("%s: file\n", fname);
407 if (SetFileAttributesA(fname, FILE_ATTRIBUTE_NORMAL) && DeleteFileA(fname))
416 /***********************************************************************
417 * DelNode (ADVPACK.@)
419 * Deletes a file or directory
422 * pszFileOrDirName [I] Name of file or directory to delete
423 * dwFlags [I] Flags; see include/advpub.h
431 * - Native version apparently does a lot of checking to make sure
432 * we're not trying to delete a system directory etc.
434 HRESULT WINAPI DelNode( LPCSTR pszFileOrDirName, DWORD dwFlags )
436 CHAR fname[MAX_PATH];
437 HRESULT ret = E_FAIL;
439 FIXME("(%s, 0x%08lx): flags ignored\n", debugstr_a(pszFileOrDirName), dwFlags);
440 if (pszFileOrDirName && *pszFileOrDirName)
442 lstrcpyA(fname, pszFileOrDirName);
444 /* TODO: Should check for system directory deletion etc. here */
446 ret = DELNODE_recurse_dirtree(fname, dwFlags);
452 /***********************************************************************
453 * DelNodeRunDLL32 (ADVPACK.@)
458 HRESULT WINAPI DelNodeRunDLL32( HWND hWnd, HINSTANCE hInst, LPSTR cmdline, INT show )
460 FIXME("(%s): stub\n", debugstr_a(cmdline));
464 /***********************************************************************
465 * ExecuteCab (ADVPACK.@)
470 HRESULT WINAPI ExecuteCab( HWND hwnd, PCABINFO pCab, LPVOID pReserved )
472 FIXME("(%p %p %p): stub\n", hwnd, pCab, pReserved);
476 /***********************************************************************
477 * ExtractFiles (ADVPACK.@)
483 HRESULT WINAPI ExtractFiles ( LPCSTR CabName, LPCSTR ExpandDir, DWORD Flags,
484 LPCSTR FileList, LPVOID LReserved, DWORD Reserved)
486 FIXME("(%p %p 0x%08lx %p %p 0x%08lx): stub\n", CabName, ExpandDir, Flags,
487 FileList, LReserved, Reserved);
491 /***********************************************************************
492 * TranslateInfString (ADVPACK.@)
494 * Translates the value of a specified key in an inf file into the
495 * current locale by expanding string macros.
498 * pszInfFilename [I] Filename of the inf file.
499 * pszInstallSection [I]
500 * pszTranslateSection [I] Inf section where the key exists.
501 * pszTranslateKey [I] Key to translate.
502 * pszBuffer [O] Contains the translated string on exit.
503 * dwBufferSize [I] Size on input of pszBuffer.
504 * pdwRequiredSize [O] Length of the translated key.
505 * pvReserved [I] Reserved, must be NULL.
509 * Failure: An hresult error code.
511 HRESULT WINAPI TranslateInfString(PCSTR pszInfFilename, PCSTR pszInstallSection,
512 PCSTR pszTranslateSection, PCSTR pszTranslateKey, PSTR pszBuffer,
513 DWORD dwBufferSize, PDWORD pdwRequiredSize, PVOID pvReserved)
517 TRACE("(%s %s %s %s %p %ld %p %p)\n",
518 debugstr_a(pszInfFilename), debugstr_a(pszInstallSection),
519 debugstr_a(pszTranslateSection), debugstr_a(pszTranslateKey),
520 pszBuffer, dwBufferSize,pdwRequiredSize, pvReserved);
522 if (!pszInfFilename || !pszTranslateSection ||
523 !pszTranslateKey || !pdwRequiredSize)
526 hInf = SetupOpenInfFileA(pszInfFilename, NULL, INF_STYLE_WIN4, NULL);
527 if (hInf == INVALID_HANDLE_VALUE)
528 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
530 if (!SetupGetLineTextA(NULL, hInf, pszTranslateSection, pszTranslateKey,
531 pszBuffer, dwBufferSize, pdwRequiredSize))
533 if (dwBufferSize < *pdwRequiredSize)
534 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
536 return SPAPI_E_LINE_NOT_FOUND;