Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2487 lines
64 KiB

  1. #include "inspch.h"
  2. #include "inseng.h"
  3. #include "resource.h"
  4. #include "insobj.h"
  5. #include "advpub.h"
  6. #include "capi.h"
  7. #include "util.h"
  8. #include "util2.h"
  9. #include <regstr.h>
  10. TCHAR c_gszSetupAPI[] = "setupapi.dll";
  11. TCHAR c_gszAdvpext[] = "advpext.dll";
  12. // A reusable buffer for logging. Note there is a possible threading
  13. // issue here as two threads may use this at the same time! I am choosing
  14. // not to protect it for performance reasons but be careful!!
  15. char szLogBuf[512];
  16. // NT reboot
  17. //
  18. #define MSDOWNLOAD "msdownld.tmp"
  19. #define DOWNLDSUB "download"
  20. // functions
  21. BOOL IfNotExistCreateDir( LPTSTR lpDir, BOOL bHidden, BOOL bRemoveFileIfExist );
  22. BOOL CheckImageHlp_dll();
  23. char g_szWindowsDir[MAX_PATH] = { 0 };
  24. #define MAXRETRIES 100
  25. BOOL GetUniqueFileName(LPCSTR pszRoot, LPCSTR pszPrefix, UINT uStartIndex, LPSTR pszBuffer)
  26. {
  27. char pszTemp[MAX_PATH];
  28. char pszTempname[16];
  29. // we now ignore the uStartIndex parameter, and create something random.
  30. uStartIndex = GetTickCount() % 0xFFFF9A;
  31. UINT uEndIndex = uStartIndex + MAXRETRIES;
  32. LPSTR pszEnd;
  33. pszBuffer[0] = 0;
  34. lstrcpy(pszTemp, pszRoot);
  35. pszEnd = pszTemp + lstrlen(pszTemp);
  36. do
  37. {
  38. wsprintf(pszTempname, "%s%06X.tmp", pszPrefix, uStartIndex);
  39. AddPath(pszTemp, pszTempname);
  40. if(GetFileAttributes(pszTemp) == 0xFFFFFFFF)
  41. break;
  42. uStartIndex++;
  43. *pszEnd = 0;
  44. } while (uStartIndex < uEndIndex);
  45. if(uStartIndex != uEndIndex)
  46. lstrcpy(pszBuffer, pszTemp);
  47. return ( pszBuffer[0] != 0 );
  48. }
  49. #define MIN_DISKSIZE_FOR_EXTRACT 1024 * 100
  50. #define MAX_DRIVES 26
  51. BOOL IsUsableDrive(LPSTR szRoot)
  52. {
  53. static BYTE bDrives[MAX_DRIVES] = { 0 };
  54. static UINT uUseRemovable = 0xffffffff;
  55. BOOL fUsable;
  56. UINT uType;
  57. DWORD dwOldErrorMode;
  58. if(uUseRemovable == 0xffffffff)
  59. {
  60. char sztemp[] = "X:\\";
  61. for(char ch = 'A'; ch <= 'Z'; ch++)
  62. {
  63. sztemp[0] = ch;
  64. if(GetDriveType(sztemp) == DRIVE_FIXED)
  65. {
  66. uUseRemovable = FALSE;
  67. break;
  68. }
  69. }
  70. if(uUseRemovable == 0xffffffff)
  71. uUseRemovable = TRUE;
  72. }
  73. dwOldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  74. uType = GetDriveType(szRoot);
  75. // the drive type is OK, if
  76. // it is fixed or removable AND
  77. // it is bigger than MIN_DISKSIZE_FOR_EXTRACT AND
  78. // GetFileAttributes succeeds
  79. //
  80. if ( (!bDrives[szRoot[0] - 'A']) &&
  81. ((uType == DRIVE_REMOVABLE && uUseRemovable) || (uType == DRIVE_FIXED)) &&
  82. ( GetFileAttributes( szRoot ) != 0xffffffff) &&
  83. ( GetDriveSize(szRoot) >= MIN_DISKSIZE_FOR_EXTRACT ) )
  84. {
  85. fUsable = TRUE;
  86. }
  87. else
  88. {
  89. bDrives[szRoot[0] - 'A'] = 1;
  90. fUsable = FALSE;
  91. }
  92. SetErrorMode(dwOldErrorMode);
  93. return fUsable;
  94. }
  95. BOOL IsDirWriteable(LPSTR lpDir)
  96. {
  97. char szFile[MAX_PATH];
  98. HANDLE hFile;
  99. BOOL bWriteAccess = FALSE;
  100. lstrcpy(szFile, lpDir);
  101. AddPath(szFile, "~!~ie6.~!~");
  102. hFile = CreateFile(szFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  103. if (hFile != INVALID_HANDLE_VALUE)
  104. {
  105. bWriteAccess = TRUE;
  106. CloseHandle(hFile);
  107. DeleteFile(szFile);
  108. }
  109. return bWriteAccess;
  110. }
  111. //=--------------------------------------------------------------------------=
  112. // Function name here
  113. //=--------------------------------------------------------------------------=
  114. // Function description
  115. //
  116. // Parameters:
  117. //
  118. // Returns:
  119. //
  120. // Notes:
  121. //
  122. // BUGBUG: Currently we have two problems :
  123. // 1. Always assume cache drive == win drive
  124. // 2. Compression isn't accounted for on stuff going to cache
  125. HRESULT CreateTempDir( DWORD dwDownloadSize,
  126. DWORD dwExtractSize,
  127. char chInstallDrive, DWORD dwInstallSize,
  128. DWORD dwWindowsDriveSize,
  129. LPSTR pszBuf, DWORD dwBufSize, DWORD dwFlag )
  130. {
  131. char szRoot[MAX_PATH];
  132. char szUnique[MAX_PATH];
  133. DWORD dwReqSize;
  134. DWORD dwReqSizeWin = 0;
  135. DWORD dwReqSizeOther = 0;
  136. DWORD dwVolFlags;
  137. DWORD dwCompressFactor;
  138. if ( !pszBuf || (dwBufSize==0) )
  139. {
  140. return ( E_INVALIDARG );
  141. }
  142. if(g_szWindowsDir[0] == 0)
  143. {
  144. GetWindowsDirectory(g_szWindowsDir, sizeof(g_szWindowsDir));
  145. }
  146. // Make sure there is enough install space on drive
  147. dwReqSizeWin = dwWindowsDriveSize;
  148. if(chInstallDrive == g_szWindowsDir[0])
  149. dwReqSizeWin += dwInstallSize;
  150. else
  151. dwReqSizeOther = dwInstallSize;
  152. if(dwReqSizeWin > 0)
  153. {
  154. lstrcpyn(szRoot, g_szWindowsDir, 4);
  155. if(!IsEnoughSpace(szRoot, dwReqSizeWin))
  156. return E_FAIL;
  157. }
  158. if(dwReqSizeOther > 0)
  159. {
  160. lstrcpyn(szRoot, g_szWindowsDir, 4);
  161. szRoot[0] = chInstallDrive;
  162. if(!IsEnoughSpace(szRoot, dwReqSizeOther))
  163. return E_FAIL;
  164. }
  165. lstrcpy( szRoot, "A:\\" );
  166. while ( szRoot[0] <= 'Z' )
  167. {
  168. UINT uType;
  169. uType = GetDriveType(szRoot);
  170. // even the drive type is OK, verify the drive has valid connection
  171. //
  172. if ( !IsUsableDrive(szRoot) )
  173. {
  174. szRoot[0]++;
  175. continue;
  176. }
  177. if(!IsDirWriteable(szRoot))
  178. {
  179. szRoot[0]++;
  180. continue;
  181. }
  182. if(!GetVolumeInformation(szRoot, NULL, 0, NULL, NULL, &dwVolFlags, NULL, 0))
  183. {
  184. szRoot[0]++;
  185. continue;
  186. }
  187. if(dwVolFlags & FS_VOL_IS_COMPRESSED)
  188. dwCompressFactor = 19;
  189. else
  190. dwCompressFactor = 10;
  191. // suitable drive:
  192. dwReqSize = (dwDownloadSize * dwCompressFactor)/10;
  193. dwReqSize += dwExtractSize;
  194. if(g_szWindowsDir[0] == szRoot[0])
  195. dwReqSize += dwReqSizeWin;
  196. else if(chInstallDrive == szRoot[0])
  197. dwReqSize += dwReqSizeOther;
  198. if ( !IsEnoughSpace( szRoot, dwReqSize ) )
  199. {
  200. szRoot[0]++;
  201. continue;
  202. }
  203. // if our suitable drive happens also to be the windows drive,
  204. // create msdownld.tmp of of it.
  205. if(szRoot[0] == g_szWindowsDir[0])
  206. lstrcpy(szRoot, g_szWindowsDir);
  207. AddPath( szRoot, MSDOWNLOAD );
  208. if ( !IfNotExistCreateDir( szRoot, TRUE, TRUE ) )
  209. {
  210. TryNextDrive:
  211. szRoot[0]++;
  212. szRoot[3] = '\0';
  213. continue;
  214. }
  215. // BUGBUG: On NT, it always tries with sequential numbers ASE1.TMP, ASE2.TMP
  216. // ASE3.TMP, etc. and if there is already a directory by this name
  217. // it fails the call instead of trying again with next number!
  218. //
  219. if ( !GetUniqueFileName(szRoot,"AS", 0, szUnique) )
  220. goto TryNextDrive ;
  221. lstrcpy(szRoot, szUnique);
  222. if ( !IfNotExistCreateDir( szRoot, FALSE, FALSE) )
  223. {
  224. goto TryNextDrive;
  225. }
  226. // you got the good dir
  227. AddPath( szRoot, "" );
  228. if ( (DWORD) lstrlen(szRoot)+1 > dwBufSize )
  229. {
  230. return ( E_INVALIDARG );
  231. }
  232. // success
  233. lstrcpy( pszBuf, szRoot );
  234. return S_OK;
  235. }
  236. // no drive has enough space
  237. return( E_FAIL );
  238. }
  239. void CleanUpTempDir(LPCSTR szTemp)
  240. {
  241. char szBuf[MAX_PATH];
  242. char szWinDir[MAX_PATH];
  243. lstrcpy(szBuf, szTemp);
  244. DelNode(szBuf, 0);
  245. // clean up msdownld.tmp if its not the windows drive
  246. GetWindowsDirectory(szWinDir, sizeof(szWinDir));
  247. if(!ANSIStrStrI(szBuf, szWinDir))
  248. {
  249. GetParentDir(szBuf);
  250. DelNode(szBuf, ADN_DEL_IF_EMPTY);
  251. }
  252. }
  253. //=--------------------------------------------------------------------------=
  254. // Function name here
  255. //=--------------------------------------------------------------------------=
  256. // Function description
  257. //
  258. // Parameters:
  259. //
  260. // Returns:
  261. //
  262. // Notes:
  263. //
  264. // Checks the install destination dir free disk space
  265. //
  266. BOOL IsEnoughSpace( LPCSTR szPath, DWORD dwInstNeedSize )
  267. {
  268. char szRoot[4];
  269. lstrcpyn(szRoot, szPath, 4);
  270. if( szRoot[0] == 0)
  271. return FALSE;
  272. if ( dwInstNeedSize + 1 > GetSpace(szRoot) )
  273. return FALSE;
  274. else
  275. return TRUE;
  276. }
  277. void SafeAddPath(LPSTR szPath, LPCSTR szName, DWORD dwPathSize)
  278. {
  279. LPSTR szTmp;
  280. DWORD dwLen = lstrlen(szPath);
  281. if(dwLen + 1 >= dwPathSize)
  282. return;
  283. // Find end of the string
  284. szTmp = szPath + dwLen;
  285. // If no trailing backslash then add one
  286. if ( szTmp > szPath && *(AnsiPrev( szPath, szTmp )) != '\\' )
  287. *(szTmp++) = '\\';
  288. *szTmp = 0;
  289. // Add new name to existing path string
  290. while ( *szName == ' ' ) szName++;
  291. lstrcpyn( szTmp, szName, dwPathSize - lstrlen(szPath) );
  292. }
  293. //=--------------------------------------------------------------------------=
  294. // Function name here
  295. //=--------------------------------------------------------------------------=
  296. // Function description
  297. //
  298. // Parameters:
  299. //
  300. // Returns:
  301. //
  302. // Notes:
  303. //
  304. BOOL IfNotExistCreateDir( LPTSTR lpDir, BOOL bHidden, BOOL bRemoveFileIfExist)
  305. {
  306. DWORD attr;
  307. attr = GetFileAttributes( lpDir );
  308. if ((attr != -1) && !(attr & FILE_ATTRIBUTE_DIRECTORY))
  309. {
  310. // lpDir does not have a directory attribute
  311. // If we are allowed to delete the file, try do that.
  312. if (bRemoveFileIfExist)
  313. {
  314. SetFileAttributes(lpDir, FILE_ATTRIBUTE_NORMAL);
  315. DeleteFile(lpDir);
  316. attr = GetFileAttributes( lpDir );
  317. }
  318. }
  319. if (attr == -1)
  320. {
  321. if ( CreateDirectory( lpDir, NULL ) )
  322. {
  323. if(bHidden)
  324. return (SetFileAttributes( lpDir, FILE_ATTRIBUTE_HIDDEN ) );
  325. else
  326. return TRUE;
  327. }
  328. else
  329. return FALSE;
  330. }
  331. return (attr & FILE_ATTRIBUTE_DIRECTORY);
  332. }
  333. //=--------------------------------------------------------------------------=
  334. // Function name here
  335. //=--------------------------------------------------------------------------=
  336. // Function description
  337. //
  338. // Parameters:
  339. //
  340. // Returns:
  341. //
  342. // Notes:
  343. //
  344. HRESULT LaunchProcess(LPCSTR pszCmd, HANDLE *phProc, LPCSTR pszDir, UINT uShow)
  345. {
  346. STARTUPINFO startInfo;
  347. PROCESS_INFORMATION processInfo;
  348. HRESULT hr = S_OK;
  349. BOOL fRet;
  350. if(phProc)
  351. *phProc = NULL;
  352. // Create process on pszCmd
  353. ZeroMemory(&startInfo, sizeof(startInfo));
  354. startInfo.cb = sizeof(startInfo);
  355. startInfo.dwFlags |= STARTF_USESHOWWINDOW;
  356. startInfo.wShowWindow = (USHORT)uShow;
  357. fRet = CreateProcess(NULL, (LPSTR) pszCmd, NULL, NULL, FALSE,
  358. NORMAL_PRIORITY_CLASS, NULL, pszDir, &startInfo, &processInfo);
  359. if(!fRet)
  360. return E_FAIL;
  361. if(phProc)
  362. *phProc = processInfo.hProcess;
  363. else
  364. CloseHandle(processInfo.hProcess);
  365. CloseHandle(processInfo.hThread);
  366. return S_OK;
  367. }
  368. //=--------------------------------------------------------------------------=
  369. // Function name here
  370. //=--------------------------------------------------------------------------=
  371. // Function description
  372. //
  373. // Parameters:
  374. //
  375. // Returns:
  376. //
  377. // Notes:
  378. //
  379. HRESULT LaunchAndWait(LPSTR pszCmd, HANDLE hAbort, HANDLE *phProc, LPSTR pszDir, UINT uShow)
  380. {
  381. HRESULT hr = S_OK;
  382. hr = LaunchProcess(pszCmd, phProc, pszDir, uShow);
  383. if(SUCCEEDED(hr))
  384. {
  385. HANDLE pHandles[2];
  386. BOOL fQuit = FALSE;
  387. pHandles[0] = *phProc;
  388. if(hAbort)
  389. pHandles[1] = hAbort;
  390. DWORD dwRet;
  391. while(!fQuit)
  392. {
  393. dwRet = MsgWaitForMultipleObjects(hAbort ? 2 : 1, pHandles, FALSE, INFINITE, QS_ALLINPUT);
  394. // Give abort the highest priority
  395. if(dwRet == WAIT_OBJECT_0)
  396. {
  397. fQuit = TRUE;
  398. }
  399. else if((dwRet == WAIT_OBJECT_0 + 1) && hAbort)
  400. {
  401. // Any abort work?
  402. hr = E_ABORT;
  403. fQuit = TRUE;
  404. }
  405. else
  406. {
  407. MSG msg;
  408. // read all of the messages in this next loop
  409. // removing each message as we read it
  410. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  411. {
  412. // if it's a quit message we're out of here
  413. if (msg.message == WM_QUIT)
  414. fQuit = TRUE;
  415. else
  416. {
  417. // otherwise dispatch it
  418. DispatchMessage(&msg);
  419. } // end of PeekMessage while loop
  420. }
  421. }
  422. }
  423. }
  424. return hr;
  425. }
  426. //=--------------------------------------------------------------------------=
  427. // Function name here
  428. //=--------------------------------------------------------------------------=
  429. // Function description
  430. //
  431. // Parameters:
  432. //
  433. // Returns:
  434. //
  435. // Notes:
  436. //
  437. void ConvertVersionStrToDwords(LPSTR pszVer, LPDWORD pdwVer, LPDWORD pdwBuild)
  438. {
  439. DWORD dwTemp1,dwTemp2;
  440. dwTemp1 = GetIntField(pszVer, 0, 0);
  441. dwTemp2 = GetIntField(pszVer, 1, 0);
  442. *pdwVer = (dwTemp1 << 16) + dwTemp2;
  443. dwTemp1 = GetIntField(pszVer, 2, 0);
  444. dwTemp2 = GetIntField(pszVer, 3, 0);
  445. *pdwBuild = (dwTemp1 << 16) + dwTemp2;
  446. }
  447. /*
  448. void ConvertVersionStr(LPSTR pszVer, WORD rwVer[])
  449. {
  450. LPSTR pszMyVer = MakeAnsiStrFromAnsi(pszVer);
  451. LPSTR pszEnd = pszMyVer + lstrlen(pszMyVer);
  452. LPSTR pszTemp = pszMyVer;
  453. LPSTR pszBegin;
  454. for(int i = 0; i < NUM_VERSION_ENTRIES; i++)
  455. rwVer[i] = 0;
  456. for(i = 0; i < 4 && pszTemp < pszEnd; i++)
  457. {
  458. pszBegin = pszTemp;
  459. while(pszTemp < pszEnd && *pszTemp != ',')
  460. pszTemp++;
  461. *pszTemp = 0;
  462. rwVer[i] = (WORD) AtoL(pszBegin);
  463. pszTemp++;
  464. }
  465. CoTaskMemFree(pszMyVer);
  466. }
  467. */
  468. //=--------------------------------------------------------------------------=
  469. // Function name here
  470. //=--------------------------------------------------------------------------=
  471. // Function description
  472. //
  473. // Parameters:
  474. //
  475. // Returns:
  476. // -1 Ver1 < Ver2
  477. // 0 Ver1 == Ver2
  478. // 1 Ver1 > Ver2
  479. // Notes:
  480. int VersionCmp(WORD rwVer1[], WORD rwVer2[])
  481. {
  482. /*
  483. for(int i = 0; i < NUM_VERSION_ENTRIES; i++)
  484. {
  485. if(rwVer1[i] < rwVer2[i])
  486. return -1;
  487. if(rwVer1[i] > rwVer2[i])
  488. return 1;
  489. }
  490. */
  491. return 0;
  492. }
  493. //=--------------------------------------------------------------------------=
  494. // Function name here
  495. //=--------------------------------------------------------------------------=
  496. // Function description
  497. //
  498. // Parameters:
  499. //
  500. // Returns:
  501. //
  502. // Notes:
  503. //
  504. int ErrMsgBox(LPSTR pszText, LPCSTR pszTitle, UINT mbFlags)
  505. {
  506. HWND hwndActive;
  507. int id;
  508. hwndActive = GetActiveWindow();
  509. id = MessageBox(hwndActive, pszText, pszTitle, mbFlags | MB_ICONERROR | MB_TASKMODAL);
  510. return id;
  511. }
  512. //=--------------------------------------------------------------------------=
  513. // Function name here
  514. //=--------------------------------------------------------------------------=
  515. // Function description
  516. //
  517. // Parameters:
  518. //
  519. // Returns:
  520. //
  521. // Notes:
  522. //
  523. int LoadSz(UINT id, LPSTR pszBuf, UINT cMaxSize)
  524. {
  525. if(cMaxSize == 0)
  526. return 0;
  527. pszBuf[0] = 0;
  528. return LoadString(g_hInstance, id, pszBuf, cMaxSize);
  529. }
  530. //=--------------------------------------------------------------------------=
  531. // Function name here
  532. //=--------------------------------------------------------------------------=
  533. // Function description
  534. //
  535. // Parameters:
  536. //
  537. // Returns:
  538. //
  539. // Notes:
  540. //
  541. LPSTR FindChar(LPSTR pszStr, char ch)
  542. {
  543. while( *pszStr != 0 && *pszStr != ch )
  544. {
  545. if (*pszStr == '\"')
  546. {
  547. // Move past the first "
  548. pszStr++;
  549. // Now keep scanning till find the closing ". After that return to scanning
  550. // for the user-given delimiter 'ch'.
  551. while( *pszStr != 0 && *pszStr != '\"' )
  552. pszStr++;
  553. // Have reached end of string without finding closing ", return now.
  554. if (*pszStr == 0)
  555. break;
  556. }
  557. pszStr++;
  558. }
  559. return pszStr;
  560. }
  561. //=--------------------------------------------------------------------------=
  562. // Function name here
  563. //=--------------------------------------------------------------------------=
  564. // Function description
  565. //
  566. // Parameters:
  567. //
  568. // Returns:
  569. //
  570. // Notes:
  571. // This is a very hacky function that will strip quotes.
  572. // Note it chages the contents of the buffer passed to it!!
  573. LPSTR StripQuotes(LPSTR pszStr)
  574. {
  575. if(!pszStr)
  576. return NULL;
  577. UINT uEnd = lstrlenA(pszStr);
  578. if(uEnd > 0 && pszStr[uEnd-1] == '"' && *pszStr == '"')
  579. {
  580. pszStr[uEnd-1] = 0;
  581. pszStr++;
  582. }
  583. return pszStr;
  584. }
  585. //=--------------------------------------------------------------------------=
  586. // Function name here
  587. //=--------------------------------------------------------------------------=
  588. // Function description
  589. //
  590. // Parameters:
  591. //
  592. // Returns:
  593. //
  594. // Notes:
  595. //
  596. DWORD WINAPI LaunchInfCommand(void *p)
  597. {
  598. HRESULT hr = S_OK;
  599. INF_ARGUEMENTS *pinfArgs = (INF_ARGUEMENTS *)p;
  600. if(pinfArgs->dwType == InfExCommand)
  601. {
  602. CABINFO cabinfo;
  603. cabinfo.pszCab = pinfArgs->szCab;
  604. cabinfo.pszInf = pinfArgs->szInfname;
  605. cabinfo.pszSection = pinfArgs->szSection;
  606. lstrcpy(cabinfo.szSrcPath, pinfArgs->szDir);
  607. cabinfo.dwFlags = pinfArgs->dwFlags;
  608. hr = ExecuteCab(NULL, &cabinfo, 0);
  609. }
  610. else
  611. {
  612. hr = RunSetupCommand(NULL, pinfArgs->szInfname,
  613. lstrlen(pinfArgs->szSection) ? pinfArgs->szSection : NULL,
  614. pinfArgs->szDir, NULL, NULL, pinfArgs->dwFlags, NULL );
  615. }
  616. return hr;
  617. }
  618. //=--------------------------------------------------------------------------=
  619. // Function name here
  620. //=--------------------------------------------------------------------------=
  621. // Function description
  622. //
  623. // Parameters:
  624. //
  625. // Returns:
  626. //
  627. // Notes:
  628. //
  629. #define ABOUTTWODAYSTIME 0x000000C9
  630. void CleanupDir(LPSTR lpDir)
  631. {
  632. char szFile[MAX_PATH];
  633. WIN32_FIND_DATA fileData;
  634. HANDLE hFindFile;
  635. FILETIME currenttime;
  636. if ( lpDir == NULL || *lpDir == '\0' )
  637. return;
  638. lstrcpy( szFile, lpDir );
  639. if ( szFile[ lstrlen(szFile)-1 ] != '\\' )
  640. lstrcat( szFile, "\\" );
  641. lstrcat( szFile, "*.tmp" );
  642. hFindFile = FindFirstFile( szFile, &fileData );
  643. if ( hFindFile == INVALID_HANDLE_VALUE )
  644. return;
  645. do
  646. {
  647. if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  648. {
  649. if ( lstrcmp( fileData.cFileName, "." ) == 0 ||
  650. lstrcmp( fileData.cFileName, ".." ) == 0 )
  651. continue;
  652. GetSystemTimeAsFileTime(&currenttime);
  653. if( ( currenttime.dwHighDateTime >
  654. fileData.ftLastWriteTime.dwHighDateTime ) &&
  655. ( currenttime.dwHighDateTime -
  656. fileData.ftLastWriteTime.dwHighDateTime > ABOUTTWODAYSTIME))
  657. {
  658. lstrcpy( szFile, lpDir );
  659. if ( szFile[ lstrlen(szFile)-1 ] != '\\' )
  660. lstrcat( szFile, "\\" );
  661. // delete the sub-dir
  662. lstrcat( szFile, fileData.cFileName );
  663. SetFileAttributes(szFile, FILE_ATTRIBUTE_NORMAL );
  664. DelNode( szFile, 0 );
  665. }
  666. }
  667. else
  668. continue;
  669. } while ( FindNextFile( hFindFile, &fileData ) );
  670. FindClose( hFindFile );
  671. }
  672. //=--------------------------------------------------------------------------=
  673. // Function name here
  674. //=--------------------------------------------------------------------------=
  675. // Function description
  676. //
  677. // Parameters:
  678. //
  679. // Returns:
  680. //
  681. // Notes:
  682. //
  683. DWORD WINAPI CleanUpAllDirs(LPVOID pv)
  684. {
  685. char szDir[MAX_PATH];
  686. UINT uType;
  687. DllAddRef();
  688. if(g_szWindowsDir[0] == 0)
  689. {
  690. GetWindowsDirectory(g_szWindowsDir, sizeof(g_szWindowsDir));
  691. }
  692. lstrcpy( szDir, "X:\\" );
  693. for(char chDrive = 'A'; chDrive <= 'Z'; chDrive++)
  694. {
  695. szDir[0] = chDrive;
  696. if (IsUsableDrive(szDir))
  697. {
  698. if(chDrive == g_szWindowsDir[0])
  699. lstrcpy(szDir, g_szWindowsDir);
  700. AddPath(szDir, MSDOWNLOAD);
  701. CleanupDir(szDir);
  702. szDir[3] = 0;
  703. }
  704. }
  705. DllRelease();
  706. return 0;
  707. }
  708. //=--------------------------------------------------------------------------=
  709. // Function name here
  710. //=--------------------------------------------------------------------------=
  711. // Function description
  712. //
  713. // Parameters:
  714. //
  715. // Returns:
  716. //
  717. // Notes:
  718. //
  719. BOOL IsCabFile(LPCSTR pszFile)
  720. {
  721. DWORD dwLen = lstrlenA(pszFile);
  722. if(dwLen <= 3)
  723. return FALSE;
  724. LPCSTR pszExt = pszFile + (dwLen - 4);
  725. if(lstrcmpiA(pszExt, ".cab") == 0)
  726. {
  727. return TRUE;
  728. }
  729. return FALSE;
  730. }
  731. typedef HRESULT (WINAPI *WINVERIFYTRUST) (HWND hwnd, GUID *pgActionID, LPVOID pWintrustData);
  732. // BUGBUG: get rid of this once moved to winbase.h!!!
  733. // #define WIN_TRUST_SUBJTYPE_CABINET \
  734. // { 0xd17c5374, \
  735. // 0xa392, \
  736. // 0x11cf, \
  737. // { 0x9d, 0xf5, 0x0, 0xaa, 0x0, 0xc1, 0x84, 0xe0 } \
  738. // }
  739. // PublishedSoftwareNoBad {C6B2E8D0-E005-11cf-A134-00C04FD7BF43}
  740. #define WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI \
  741. { 0xc6b2e8d0, \
  742. 0xe005, \
  743. 0x11cf, \
  744. { 0xa1, 0x34, 0x0, 0xc0, 0x4f, 0xd7, 0xbf, 0x43 } \
  745. }
  746. #define WINTRUST "wintrust.dll"
  747. // Verion number 5.0
  748. #define AUTHENTICODE2_MS_VERSION 0x00050000
  749. // Build number 1542.32
  750. #define AUTHENTICODE2_LS_VERSION 0x06050020
  751. //=--------------------------------------------------------------------------=
  752. // Function name here
  753. //=--------------------------------------------------------------------------=
  754. // Function description
  755. //
  756. // Parameters:
  757. //
  758. // Returns:
  759. //
  760. // Notes:
  761. //
  762. HRESULT CheckTrustIE3(LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt);
  763. HRESULT CheckTrustIE4(LPCSTR szURL, LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt);
  764. HRESULT WINAPI CheckTrustEx(LPCSTR szURL, LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, DWORD dwReserved)
  765. {
  766. WINVERIFYTRUST pwvt;
  767. HINSTANCE hinst;
  768. char szPath[MAX_PATH] = { 0 };
  769. DWORD dwVerMS = 0;
  770. DWORD dwVerLS = 0;
  771. HRESULT hr = S_OK;
  772. static BOOL st_CheckTrust = TRUE ;
  773. static BOOL st_Auth2Checked = FALSE;
  774. if (!st_CheckTrust)
  775. return S_FALSE ;
  776. if (!CheckImageHlp_dll())
  777. {
  778. st_CheckTrust = FALSE;
  779. return S_FALSE ;
  780. }
  781. hinst = LoadLibrary(WINTRUST);
  782. if(!hinst)
  783. {
  784. //
  785. st_CheckTrust = FALSE ;
  786. return S_FALSE;
  787. }
  788. if (!st_Auth2Checked)
  789. {
  790. // If we get here, we know we can load Wintrust.dll
  791. GetSystemDirectory(szPath, sizeof(szPath));
  792. AddPath(szPath, "Softpub.dll");
  793. GetVersionFromFile(szPath, &dwVerMS, &dwVerLS, TRUE);
  794. // If softpubs version is less then the authenticode2 version don't call WinverifyTrust.
  795. if ((dwVerMS < AUTHENTICODE2_MS_VERSION) ||
  796. ((dwVerMS == AUTHENTICODE2_MS_VERSION) && (dwVerLS < AUTHENTICODE2_LS_VERSION)) )
  797. {
  798. hr = S_FALSE;
  799. st_CheckTrust = FALSE;
  800. }
  801. st_Auth2Checked = TRUE;
  802. }
  803. if (st_CheckTrust)
  804. {
  805. pwvt = (WINVERIFYTRUST) GetProcAddress(hinst, "WinVerifyTrust");
  806. if(!pwvt)
  807. {
  808. FreeLibrary(hinst);
  809. st_CheckTrust = FALSE ;
  810. return S_FALSE;
  811. }
  812. // If we don't have a URL, use the IE3 methode of CheckTrust.
  813. hr = TRUST_E_PROVIDER_UNKNOWN;
  814. if (szURL)
  815. {
  816. // The new way of calling into WinVerifyTrust wll return TRUST_E_PROVIDER_UNKNOWN
  817. // if the new methode is not implemented on the system.
  818. __try
  819. {
  820. hr = CheckTrustIE4(szURL, szFilename, hwndForUI, bShowBadUI, pwvt);
  821. }
  822. __except(EXCEPTION_EXECUTE_HANDLER)
  823. {
  824. //Corrupted Java.
  825. hr = TRUST_E_FAIL;
  826. }
  827. }
  828. if (hr == TRUST_E_PROVIDER_UNKNOWN || hr == E_FAIL)
  829. {
  830. hr = CheckTrustIE3(szFilename, hwndForUI, bShowBadUI, pwvt);
  831. if (hr == S_FALSE)
  832. st_CheckTrust = FALSE;
  833. }
  834. }
  835. FreeLibrary(hinst);
  836. return hr;
  837. }
  838. HRESULT CheckTrustIE3(LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt)
  839. {
  840. HRESULT hr;
  841. LPWSTR pwszFilename = NULL;
  842. GUID PublishedSoftware = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
  843. GUID PublishedSoftwareNoBadUI = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI;
  844. GUID * ActionGUID;
  845. if(bShowBadUI)
  846. ActionGUID = &PublishedSoftware;
  847. else
  848. ActionGUID = &PublishedSoftwareNoBadUI;
  849. GUID SubjectPeImage = WIN_TRUST_SUBJTYPE_PE_IMAGE;
  850. GUID SubjectCAB = WIN_TRUST_SUBJTYPE_CABINET;
  851. WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT ActionData;
  852. WIN_TRUST_SUBJECT_FILE Subject;
  853. Subject.hFile = INVALID_HANDLE_VALUE;
  854. pwszFilename = OLESTRFROMANSI(szFilename);
  855. Subject.lpPath = pwszFilename;
  856. if (IsCabFile(szFilename))
  857. {
  858. ActionData.SubjectType = &SubjectCAB;
  859. }
  860. else
  861. {
  862. ActionData.SubjectType = &SubjectPeImage;
  863. }
  864. ActionData.Subject = &Subject;
  865. ActionData.hClientToken = NULL;
  866. hr = pwvt( hwndForUI, ActionGUID, &ActionData);
  867. if(hr == E_FAIL)
  868. {
  869. // Hopefully, this is a general "trust is screwy" error. We will put
  870. // up our own ui to see if we can continue
  871. // Is this UI OK
  872. char szTitle[128];
  873. char szMess[256];
  874. LoadSz(IDS_SECURITYTITLE, szTitle, 128);
  875. LoadSz(IDS_SECURITY, szMess, 256);
  876. if(MessageBox(hwndForUI, szMess, szTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
  877. {
  878. hr = S_FALSE;
  879. }
  880. }
  881. if(pwszFilename)
  882. CoTaskMemFree(pwszFilename);
  883. return hr;
  884. }
  885. // {D41E4F1D-A407-11d1-8BC9-00C04FA30A41}
  886. #define COR_POLICY_PROVIDER_DOWNLOAD \
  887. { 0xd41e4f1d, 0xa407, 0x11d1, {0x8b, 0xc9, 0x0, 0xc0, 0x4f, 0xa3, 0xa, 0x41 } }
  888. typedef HRESULT (WINAPI *COINTERNETCREATESECURITYMANAGER) ( IServiceProvider *pSP, IInternetSecurityManager **ppSM, DWORD dwReserved);
  889. HRESULT CheckTrustIE4(LPCSTR szURL, LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI, WINVERIFYTRUST pwvt)
  890. {
  891. GUID guidCor = COR_POLICY_PROVIDER_DOWNLOAD;
  892. GUID *pguidActionIDCor = &guidCor;
  893. LPWSTR pwszURL = NULL;
  894. GUID guidJava = JAVA_POLICY_PROVIDER_DOWNLOAD;
  895. GUID *pguidActionIDJava = &guidJava;
  896. WINTRUST_DATA wintrustData;
  897. WINTRUST_FILE_INFO fileData;
  898. JAVA_POLICY_PROVIDER javaPolicyData;
  899. HRESULT hr = S_OK;
  900. HANDLE hFile = INVALID_HANDLE_VALUE;
  901. HINSTANCE hUrlmon = NULL;
  902. IInternetSecurityManager *pSecMgr = NULL;
  903. DWORD dwZone;
  904. hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  905. if (hFile == INVALID_HANDLE_VALUE)
  906. {
  907. hr = HRESULT_FROM_WIN32(GetLastError());
  908. }
  909. else
  910. {
  911. if (hwndForUI == INVALID_HANDLE_VALUE)
  912. bShowBadUI = FALSE;
  913. pwszURL = OLESTRFROMANSI(szURL);
  914. memset(&wintrustData, 0, sizeof(wintrustData));
  915. memset(&fileData, 0, sizeof(fileData));
  916. memset(&javaPolicyData, 0, sizeof(javaPolicyData));
  917. javaPolicyData.cbSize = sizeof(JAVA_POLICY_PROVIDER);
  918. javaPolicyData.VMBased = FALSE;
  919. // obsolete: noone pays attention to this
  920. javaPolicyData.fNoBadUI = !bShowBadUI;
  921. javaPolicyData.pwszZone = pwszURL;
  922. javaPolicyData.pZoneManager = NULL;
  923. // Use a file handle, so that in case trust has to put up UI the path
  924. // to the local file does not show in hte UI if we actually downloaded the
  925. // file from a URL.
  926. fileData.cbStruct = sizeof(WINTRUST_FILE_INFO);
  927. fileData.pcwszFilePath = pwszURL;
  928. fileData.hFile = hFile;
  929. wintrustData.cbStruct = sizeof(WINTRUST_DATA);
  930. wintrustData.pPolicyCallbackData = &javaPolicyData;
  931. if (hwndForUI == INVALID_HANDLE_VALUE)
  932. wintrustData.dwUIChoice = WTD_UI_NONE;
  933. else if(bShowBadUI)
  934. wintrustData.dwUIChoice = WTD_UI_ALL;
  935. else
  936. wintrustData.dwUIChoice = WTD_UI_NOBAD;
  937. wintrustData.dwUnionChoice = WTD_CHOICE_FILE;
  938. wintrustData.pFile = &fileData;
  939. hr = pwvt( hwndForUI, pguidActionIDCor, &wintrustData);
  940. if (hr == TRUST_E_PROVIDER_UNKNOWN)
  941. {
  942. hr = pwvt( hwndForUI, pguidActionIDJava, &wintrustData);
  943. }
  944. // BUGBUG: Check with Vatsan about this bugbug.
  945. // this works around a wvt bug that returns 0x57 (success) when
  946. // you hit No to an unsigned control
  947. if (SUCCEEDED(hr) && hr != S_OK)
  948. {
  949. hr = TRUST_E_FAIL;
  950. }
  951. if (SUCCEEDED(hr))
  952. {
  953. hUrlmon = LoadLibrary("urlmon.dll");
  954. if (hUrlmon)
  955. {
  956. COINTERNETCREATESECURITYMANAGER pcicsm;
  957. pcicsm = (COINTERNETCREATESECURITYMANAGER) GetProcAddress(hUrlmon, "CoInternetCreateSecurityManager");
  958. if (pcicsm)
  959. pcicsm(NULL, &pSecMgr, NULL);
  960. }
  961. if ((javaPolicyData.pbJavaTrust == NULL) ||
  962. (!javaPolicyData.pbJavaTrust->fAllActiveXPermissions) ||
  963. (pSecMgr && SUCCEEDED(pSecMgr->MapUrlToZone(pwszURL, &dwZone, 0)) && dwZone == URLZONE_LOCAL_MACHINE && FAILED(javaPolicyData.pbJavaTrust->hVerify)))
  964. hr = TRUST_E_FAIL;
  965. if (hUrlmon)
  966. FreeLibrary(hUrlmon);
  967. }
  968. if (javaPolicyData.pbJavaTrust)
  969. CoTaskMemFree(javaPolicyData.pbJavaTrust);
  970. if(pwszURL)
  971. CoTaskMemFree(pwszURL);
  972. CloseHandle(hFile);
  973. if (pSecMgr)
  974. pSecMgr->Release();
  975. }
  976. return hr;
  977. }
  978. HRESULT WINAPI CheckTrust(LPCSTR szFilename, HWND hwndForUI, BOOL bShowBadUI)
  979. {
  980. return CheckTrustEx(NULL, szFilename, hwndForUI, bShowBadUI, NULL);
  981. }
  982. //=--------------------------------------------------------------------------=
  983. // Function name here
  984. //=--------------------------------------------------------------------------=
  985. // Function description
  986. //
  987. // Parameters:
  988. //
  989. // Returns:
  990. //
  991. // Notes:
  992. //
  993. DWORD GetStringField(LPSTR szStr, UINT uField, LPSTR szBuf, UINT cBufSize)
  994. {
  995. LPSTR pszBegin = szStr;
  996. LPSTR pszEnd;
  997. UINT i = 0;
  998. DWORD dwToCopy;
  999. if(cBufSize == 0)
  1000. return 0;
  1001. szBuf[0] = 0;
  1002. if(szStr == NULL)
  1003. return 0;
  1004. while(*pszBegin != 0 && i < uField)
  1005. {
  1006. pszBegin = FindChar(pszBegin, ',');
  1007. if(*pszBegin != 0)
  1008. pszBegin++;
  1009. i++;
  1010. }
  1011. // we reached end of string, no field
  1012. if(*pszBegin == 0)
  1013. {
  1014. return 0;
  1015. }
  1016. pszEnd = FindChar(pszBegin, ',');
  1017. while(pszBegin <= pszEnd && *pszBegin == ' ')
  1018. pszBegin++;
  1019. while(pszEnd > pszBegin && *(pszEnd - 1) == ' ')
  1020. pszEnd--;
  1021. if(pszEnd > (pszBegin + 1) && *pszBegin == '"' && *(pszEnd-1) == '"')
  1022. {
  1023. pszBegin++;
  1024. pszEnd--;
  1025. }
  1026. dwToCopy = (DWORD)(pszEnd - pszBegin + 1);
  1027. if(dwToCopy > cBufSize)
  1028. dwToCopy = cBufSize;
  1029. lstrcpynA(szBuf, pszBegin, dwToCopy);
  1030. return dwToCopy - 1;
  1031. }
  1032. DWORD GetIntField(LPSTR szStr, UINT uField, DWORD dwDefault)
  1033. {
  1034. char szNumBuf[16];
  1035. if(GetStringField(szStr, uField, szNumBuf, sizeof(szNumBuf)) == 0)
  1036. return dwDefault;
  1037. else
  1038. return AtoL(szNumBuf);
  1039. }
  1040. //=--------------------------------------------------------------------------=
  1041. // Function name here
  1042. //=--------------------------------------------------------------------------=
  1043. // Function description
  1044. //
  1045. // Parameters:
  1046. //
  1047. // Returns:
  1048. //
  1049. // Notes:
  1050. //
  1051. LPSTR BuildDependencyString(LPSTR pszName,LPSTR pszOwner)
  1052. {
  1053. LPSTR pszRet = NULL;
  1054. if(pszOwner)
  1055. {
  1056. char szBuf[128];
  1057. LoadSz(IDS_DEPENDNAME, szBuf, sizeof(szBuf));
  1058. pszRet = new char[lstrlenA(pszName) + lstrlenA(szBuf) + lstrlenA(pszOwner) + 25];
  1059. if(pszRet)
  1060. wsprintf(pszRet, szBuf, pszName, pszOwner);
  1061. }
  1062. else
  1063. {
  1064. pszRet = new char[lstrlenA(pszName) + 1];
  1065. if(pszRet)
  1066. lstrcpyA(pszRet, pszName);
  1067. }
  1068. return pszRet;
  1069. }
  1070. //=--------------------------------------------------------------------------=
  1071. // Function name here
  1072. //=--------------------------------------------------------------------------=
  1073. // Function description
  1074. //
  1075. // Parameters:
  1076. //
  1077. // Returns:
  1078. //
  1079. // Notes:
  1080. //
  1081. LPWSTR ParseURLW(BSTR str)
  1082. {
  1083. LPWSTR pwszTemp;
  1084. if(str == NULL || *str == '\0')
  1085. return NULL;
  1086. pwszTemp = str + SysStringLen(str) - 1;
  1087. while(pwszTemp >= str && *pwszTemp != '\\' && *pwszTemp != '/')
  1088. pwszTemp--;
  1089. return pwszTemp + 1;
  1090. }
  1091. //=--------------------------------------------------------------------------=
  1092. // Function name here
  1093. //=--------------------------------------------------------------------------=
  1094. // Function description
  1095. //
  1096. // Parameters:
  1097. //
  1098. // Returns:
  1099. //
  1100. // Notes:
  1101. //
  1102. LPSTR ParseURLA(LPCSTR str)
  1103. {
  1104. LPSTR pszTemp;
  1105. if(str == NULL || *str == '\0')
  1106. return NULL;
  1107. pszTemp = (LPSTR)str + lstrlen(str) - 1;
  1108. while(pszTemp >= str && *pszTemp != '\\' && *pszTemp != '/')
  1109. pszTemp--;
  1110. return pszTemp + 1;
  1111. }
  1112. //=--------------------------------------------------------------------------=
  1113. // Function name here
  1114. //=--------------------------------------------------------------------------=
  1115. // Function description
  1116. //
  1117. // Parameters:
  1118. //
  1119. // Returns:
  1120. //
  1121. // Notes:
  1122. //
  1123. LPSTR MakeAnsiStrFromAnsi(LPSTR psz)
  1124. {
  1125. LPSTR pszTmp;
  1126. if(psz == NULL)
  1127. return NULL;
  1128. pszTmp = (LPSTR) CoTaskMemAlloc(lstrlenA(psz) + 1);
  1129. if(pszTmp)
  1130. lstrcpyA(pszTmp, psz);
  1131. return pszTmp;
  1132. }
  1133. //=--------------------------------------------------------------------------=
  1134. // Function name here
  1135. //=--------------------------------------------------------------------------=
  1136. // Function description
  1137. //
  1138. // Parameters:
  1139. //
  1140. // Returns:
  1141. //
  1142. // Notes:
  1143. //
  1144. LPSTR CopyAnsiStr(LPCSTR psz)
  1145. {
  1146. LPSTR pszTmp;
  1147. if(psz == NULL)
  1148. return NULL;
  1149. pszTmp = (LPSTR) new char[lstrlenA(psz) + 1];
  1150. if(pszTmp)
  1151. lstrcpyA(pszTmp, psz);
  1152. return pszTmp;
  1153. }
  1154. //=--------------------------------------------------------------------------=
  1155. // Function name here
  1156. //=--------------------------------------------------------------------------=
  1157. // Function description
  1158. //
  1159. // Parameters:
  1160. //
  1161. // Returns:
  1162. //
  1163. // Notes:
  1164. //
  1165. BOOL DeleteKeyAndSubKeys(HKEY hkIn, LPSTR pszSubKey)
  1166. {
  1167. HKEY hk;
  1168. TCHAR szTmp[MAX_PATH];
  1169. DWORD dwTmpSize;
  1170. long l;
  1171. BOOL f;
  1172. l = RegOpenKeyEx(hkIn, pszSubKey, 0, KEY_READ | KEY_WRITE, &hk);
  1173. if (l != ERROR_SUCCESS) return FALSE;
  1174. // loop through all subkeys, blowing them away.
  1175. //
  1176. f = TRUE;
  1177. while (f) {
  1178. dwTmpSize = MAX_PATH;
  1179. l = RegEnumKeyEx(hk, 0, szTmp, &dwTmpSize, 0, NULL, NULL, NULL);
  1180. if (l != ERROR_SUCCESS) break;
  1181. f = DeleteKeyAndSubKeys(hk, szTmp);
  1182. }
  1183. // there are no subkeys left, [or we'll just generate an error and return FALSE].
  1184. // let's go blow this dude away.
  1185. //
  1186. RegCloseKey(hk);
  1187. l = RegDeleteKey(hkIn, pszSubKey);
  1188. return (l == ERROR_SUCCESS) ? TRUE : FALSE;
  1189. }
  1190. //=--------------------------------------------------------------------------=
  1191. // Function name here
  1192. //=--------------------------------------------------------------------------=
  1193. // Function description
  1194. //
  1195. // Parameters:
  1196. //
  1197. // Returns:
  1198. //
  1199. // Notes:
  1200. //
  1201. int StringFromGuid(const CLSID* piid, LPTSTR pszBuf)
  1202. {
  1203. return wsprintf(pszBuf, TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  1204. piid->Data1, piid->Data2, piid->Data3, piid->Data4[0], piid->Data4[1],
  1205. piid->Data4[2],piid->Data4[3], piid->Data4[4], piid->Data4[5],
  1206. piid->Data4[6], piid->Data4[7]);
  1207. }
  1208. //=--------------------------------------------------------------------------=
  1209. // Function name here
  1210. //=--------------------------------------------------------------------------=
  1211. // Function description
  1212. //
  1213. // Parameters:
  1214. //
  1215. // Returns:
  1216. //
  1217. // Notes:
  1218. //
  1219. LPWSTR MakeWideStrFromAnsi(LPSTR psz, BYTE bType)
  1220. {
  1221. LPWSTR pwsz;
  1222. int i;
  1223. // arg checking.
  1224. //
  1225. if (!psz)
  1226. return NULL;
  1227. // compute the length of the required BSTR
  1228. //
  1229. i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
  1230. if (i <= 0) return NULL;
  1231. // allocate the widestr
  1232. //
  1233. switch (bType) {
  1234. case STR_BSTR:
  1235. // -1 since it'll add it's own space for a NULL terminator
  1236. //
  1237. pwsz = (LPWSTR) SysAllocStringLen(NULL, i - 1);
  1238. break;
  1239. case STR_OLESTR:
  1240. pwsz = (LPWSTR) CoTaskMemAlloc(i * sizeof(WCHAR));
  1241. break;
  1242. default:
  1243. break;
  1244. }
  1245. if (!pwsz) return NULL;
  1246. MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
  1247. pwsz[i - 1] = 0;
  1248. return pwsz;
  1249. }
  1250. #define UNINSTALL_BRANCH "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
  1251. BOOL UninstallKeyExists(LPCSTR pszUninstallKey)
  1252. {
  1253. HKEY hUninstallKey = NULL;
  1254. char szUninstallStr[512];
  1255. if (!pszUninstallKey) // If the pointer is NULL, assume installed
  1256. return TRUE;
  1257. lstrcpyA(szUninstallStr, UNINSTALL_BRANCH);
  1258. lstrcatA(szUninstallStr, "\\");
  1259. lstrcatA(szUninstallStr, pszUninstallKey);
  1260. if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, szUninstallStr, 0, KEY_READ,
  1261. &hUninstallKey) == ERROR_SUCCESS)
  1262. {
  1263. RegCloseKey(hUninstallKey);
  1264. return TRUE;
  1265. }
  1266. else
  1267. return FALSE;
  1268. }
  1269. void AddTempToLikelyExtractDrive(DWORD dwTempDLSpace, DWORD dwTempExSpace,
  1270. char chInstallDrive, char chDownloadDrive,
  1271. DWORD *pdwWinDirReq, DWORD *pdwInsDirReq,
  1272. DWORD *pdwDownloadDirReq)
  1273. {
  1274. DWORD dwExNeeded, dwNeeded;
  1275. DWORD dwVolFlags, dwCompressFactor;
  1276. char szRoot[4];
  1277. DWORD dwInsDirNeeded = dwTempDLSpace + dwTempExSpace;
  1278. DWORD dwInstallDriveCompress = 10;
  1279. lstrcpy(szRoot, "A:\\");
  1280. while ( szRoot[0] <= 'Z' )
  1281. {
  1282. if (!IsUsableDrive( szRoot ) )
  1283. {
  1284. szRoot[0]++;
  1285. continue;
  1286. }
  1287. if(!GetVolumeInformation(szRoot, NULL, 0, NULL, NULL, &dwVolFlags, NULL, 0))
  1288. {
  1289. szRoot[0]++;
  1290. continue;
  1291. }
  1292. if(dwVolFlags & FS_VOL_IS_COMPRESSED)
  1293. {
  1294. dwCompressFactor = 19;
  1295. if(szRoot[0] == chInstallDrive)
  1296. dwInstallDriveCompress = 19;
  1297. }
  1298. else
  1299. dwCompressFactor = 10;
  1300. // Decide how much we need if we extract to this drive
  1301. dwExNeeded = (dwTempDLSpace * dwCompressFactor)/10 + dwTempExSpace;
  1302. dwNeeded = 0;
  1303. // if the install dir, add what is going to install dir
  1304. if(szRoot[0] == chInstallDrive)
  1305. dwNeeded += *pdwInsDirReq;
  1306. // if it is the windows dir, add what goes to win dir
  1307. if(szRoot[0] == g_szWindowsDir[0])
  1308. dwNeeded += *pdwWinDirReq;
  1309. // BUGBUG: compression on this guy?
  1310. if(szRoot[0] == chDownloadDrive)
  1311. dwNeeded += ((*pdwDownloadDirReq * dwCompressFactor)/10);
  1312. dwNeeded += dwExNeeded;
  1313. // if this drive has enough bump Req if appropiate
  1314. if(IsEnoughSpace(szRoot, dwNeeded ))
  1315. {
  1316. if(szRoot[0] == chInstallDrive)
  1317. {
  1318. *pdwInsDirReq += dwExNeeded;
  1319. }
  1320. else if(szRoot[0] == chDownloadDrive)
  1321. *pdwDownloadDirReq += dwExNeeded;
  1322. else if(szRoot[0] == g_szWindowsDir[0])
  1323. *pdwWinDirReq += dwExNeeded;
  1324. return;
  1325. }
  1326. szRoot[0]++;
  1327. }
  1328. // if we get here, NO drive has enough space.
  1329. // Add to install dir here
  1330. *pdwInsDirReq += (dwTempDLSpace * dwCompressFactor)/10 + dwTempExSpace;
  1331. }
  1332. #define INSTALLCHECK_VALUE 0
  1333. #define INSTALLCHECK_DATA 1
  1334. #define INSTALLCHECK_NOTSUPPORTED 2
  1335. // If you change the string below you also have to tell all clients which use this feature to change.
  1336. // The clients are writing there success values under this key.
  1337. #define REGSTR_SUCCESS_KEY "Software\\Microsoft\\Active Setup\\Install Check"
  1338. BOOL SuccessCheck(LPSTR pszSuccessKey)
  1339. {
  1340. HKEY hKey = NULL;
  1341. char szRegKey[512];
  1342. char szRegData[512];
  1343. DWORD dwSize;
  1344. BOOL bInstalledSuccessfull = FALSE;
  1345. if (!pszSuccessKey) // If the pointer is NULL, assume installed
  1346. return TRUE;
  1347. if (GetStringField(pszSuccessKey, INSTALLCHECK_NOTSUPPORTED, szRegKey, sizeof(szRegKey)))
  1348. return FALSE; // This format is not yet supported
  1349. if (GetStringField(pszSuccessKey, INSTALLCHECK_VALUE, szRegKey, sizeof(szRegKey)) == 0)
  1350. return TRUE; // There is not Registry value to check for. Assume OK
  1351. if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_SUCCESS_KEY, 0, KEY_READ,
  1352. &hKey) == ERROR_SUCCESS)
  1353. {
  1354. dwSize = sizeof(szRegData);
  1355. if (RegQueryValueEx(hKey, szRegKey, NULL, NULL, (LPBYTE)szRegData, &dwSize) == ERROR_SUCCESS)
  1356. {
  1357. bInstalledSuccessfull = TRUE;
  1358. // If a data filed is specified, check if the value data compare
  1359. if (GetStringField(pszSuccessKey, INSTALLCHECK_DATA, szRegKey, sizeof(szRegKey)))
  1360. {
  1361. bInstalledSuccessfull = (lstrcmpi(szRegKey, szRegData) == 0);
  1362. }
  1363. }
  1364. RegCloseKey(hKey);
  1365. }
  1366. return bInstalledSuccessfull;
  1367. }
  1368. DWORD WaitForEvent(HANDLE hEvent, HWND hwnd)
  1369. {
  1370. BOOL fQuit = FALSE;
  1371. BOOL fDone = FALSE;
  1372. DWORD dwRet;
  1373. while(!fQuit && !fDone)
  1374. {
  1375. dwRet = MsgWaitForMultipleObjects(1, &hEvent, FALSE,
  1376. INFINITE, QS_ALLINPUT);
  1377. // Give abort the highest priority
  1378. if(dwRet == WAIT_OBJECT_0)
  1379. {
  1380. fDone = TRUE;
  1381. }
  1382. else
  1383. {
  1384. MSG msg;
  1385. // read all of the messages in this next loop
  1386. // removing each message as we read it
  1387. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  1388. {
  1389. if(!hwnd || !IsDialogMessage(hwnd, &msg))
  1390. {
  1391. // if it's a quit message we're out of here
  1392. if (msg.message == WM_QUIT)
  1393. fQuit = TRUE;
  1394. else
  1395. {
  1396. // otherwise dispatch it
  1397. TranslateMessage(&msg);
  1398. DispatchMessage(&msg);
  1399. }
  1400. } // end of PeekMessage while loop
  1401. }
  1402. }
  1403. }
  1404. return (fQuit ? EVENTWAIT_QUIT : EVENTWAIT_DONE);
  1405. }
  1406. // If .CIF command switch has #W or #w, expand it to Windows directory. Otherwise, do nothing.
  1407. // Input: lpBuf : the original switches
  1408. // dwSize : buffer size
  1409. // Outout: lpBuf : expanded switches
  1410. //
  1411. void ExpandString( LPSTR lpBuf, DWORD dwSize )
  1412. {
  1413. LPSTR pTmp, pTmp1;
  1414. char ch;
  1415. if ( !lpBuf || !*lpBuf || !dwSize )
  1416. return;
  1417. pTmp = ANSIStrChr( lpBuf, '#' );
  1418. if ( pTmp )
  1419. {
  1420. pTmp1 = CharNext( pTmp );
  1421. ch = (char)CharUpper((LPSTR) *pTmp1);
  1422. if ( ch == 'W' )
  1423. {
  1424. PSTR pTmpBuf;
  1425. // #W... => <WindowsDir>...
  1426. if ( dwSize < (DWORD)( lstrlen(lpBuf) + lstrlen(g_szWindowsDir) - 1 ) )
  1427. return; // should never be here
  1428. pTmpBuf = (LPSTR)LocalAlloc( LPTR, dwSize );
  1429. if ( pTmpBuf )
  1430. {
  1431. *pTmp = '\0';
  1432. lstrcpy( pTmpBuf, lpBuf );
  1433. lstrcat( pTmpBuf, g_szWindowsDir );
  1434. lstrcat( pTmpBuf, CharNext(pTmp1) );
  1435. // re-set the output string
  1436. lstrcpy( lpBuf, pTmpBuf );
  1437. LocalFree( pTmpBuf );
  1438. }
  1439. }
  1440. else if ( ch == '#' )
  1441. {
  1442. // ##... => #...
  1443. MoveMemory( pTmp, pTmp1, lstrlen(pTmp1)+1 );
  1444. }
  1445. }
  1446. }
  1447. void DeleteFilelist(LPCSTR pszFilelist)
  1448. {
  1449. LPSTR pszSections, pszSectionsPreFail, pszTemp;
  1450. DWORD dwSize = ALLOC_CHUNK_SIZE;
  1451. DWORD dwRead;
  1452. // Get a list of all sections
  1453. //
  1454. // BUGBUG: Write this so only one call to GetPrivateProfile exists
  1455. pszSections = (LPSTR) malloc(dwSize);
  1456. // Bail out if no memory
  1457. if(!pszSections)
  1458. return;
  1459. dwRead = GetPrivateProfileStringA(NULL, NULL, "", pszSections, dwSize, pszFilelist);
  1460. while( dwRead >= (dwSize - 2) )
  1461. {
  1462. dwSize += ALLOC_CHUNK_SIZE;
  1463. pszSectionsPreFail = pszSections;
  1464. #pragma prefast(suppress: 308, "Noise - pointer was saved")
  1465. pszSections = (LPSTR) realloc(pszSections, dwSize);
  1466. if(!pszSections)
  1467. {
  1468. free(pszSectionsPreFail);
  1469. dwRead = 0;
  1470. break;
  1471. }
  1472. dwRead = GetPrivateProfileStringA(NULL, NULL, "", pszSections, dwSize, pszFilelist);
  1473. }
  1474. pszTemp = pszSections;
  1475. dwSize = lstrlenA(pszTemp);
  1476. while(dwSize != 0)
  1477. {
  1478. WritePrivateProfileSection(pszTemp, NULL, pszFilelist);
  1479. pszTemp += (dwSize + 1);
  1480. dwSize = lstrlenA(pszTemp);
  1481. }
  1482. free(pszSections);
  1483. }
  1484. BOOL WaitForMutex(HANDLE hMutex)
  1485. {
  1486. BOOL fQuit = FALSE;
  1487. while (MsgWaitForMultipleObjects(1, &hMutex, FALSE, INFINITE, QS_ALLINPUT) != WAIT_OBJECT_0)
  1488. {
  1489. MSG msg;
  1490. while (!fQuit && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  1491. {
  1492. if (msg.message == WM_QUIT)
  1493. fQuit = TRUE;
  1494. else
  1495. {
  1496. TranslateMessage(&msg);
  1497. DispatchMessage(&msg);
  1498. }
  1499. }
  1500. }
  1501. return fQuit;
  1502. }
  1503. BOOL IsNT()
  1504. {
  1505. static int st_IsNT = 0xffff;
  1506. if(st_IsNT == 0xffff)
  1507. {
  1508. OSVERSIONINFO verinfo; // Version Check
  1509. verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1510. if ( GetVersionEx( &verinfo ) != FALSE )
  1511. {
  1512. if( verinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
  1513. st_IsNT = 0;
  1514. else if ( verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
  1515. st_IsNT = 1;
  1516. }
  1517. }
  1518. return (st_IsNT == 1) ? TRUE : FALSE;
  1519. }
  1520. HINSTANCE InitSetupLib(LPCSTR pszInfName, HINF *phinf)
  1521. {
  1522. HINSTANCE hInst = NULL;
  1523. *phinf = NULL;
  1524. if( IsNT() )
  1525. {
  1526. hInst = LoadLibrary("setupapi.dll");
  1527. OpenINFEngine( pszInfName, NULL, 0, phinf, NULL );
  1528. }
  1529. else
  1530. {
  1531. hInst = LoadLibrary("w95inf32.dll");
  1532. }
  1533. return hInst;
  1534. }
  1535. void FreeSetupLib(HINSTANCE hInst, HINF hInf)
  1536. {
  1537. if(hInf)
  1538. CloseINFEngine(hInf);
  1539. if(hInst)
  1540. FreeLibrary(hInst);
  1541. }
  1542. HRESULT MyTranslateInfString( PCSTR pszInfFilename, PCSTR pszInstallSection,
  1543. PCSTR pszTranslateSection, PCSTR pszTranslateKey,
  1544. PSTR pszBuffer, DWORD dwBufferSize,
  1545. PDWORD pdwRequiredSize, HINF hInf )
  1546. {
  1547. HRESULT hr;
  1548. if(IsNT() && hInf)
  1549. {
  1550. hr = TranslateInfStringEx( hInf, pszInfFilename, pszTranslateSection, pszTranslateKey,
  1551. pszBuffer, dwBufferSize,
  1552. pdwRequiredSize, NULL );
  1553. }
  1554. else
  1555. {
  1556. hr = TranslateInfString( pszInfFilename, pszInstallSection, pszTranslateSection, pszTranslateKey,
  1557. pszBuffer, dwBufferSize,
  1558. pdwRequiredSize, NULL);
  1559. }
  1560. return hr;
  1561. }
  1562. #define UNUSED_STRING "xxx"
  1563. HRESULT MyTranslateString( LPCSTR pszCif, LPCSTR pszID, LPCSTR pszTranslateKey,
  1564. LPSTR pszBuffer, DWORD dwBufferSize)
  1565. {
  1566. HRESULT hr = E_FAIL;
  1567. char szTemp[512];
  1568. if(GetPrivateProfileString(pszID, pszTranslateKey, "", pszBuffer, dwBufferSize, pszCif))
  1569. {
  1570. //bad code
  1571. DWORD dwLen = lstrlen(pszBuffer);
  1572. if(dwLen > 2)
  1573. {
  1574. // Cut the last %, and then look up in string section
  1575. if(pszBuffer[0] == '%' && pszBuffer[dwLen - 1] == '%')
  1576. {
  1577. pszBuffer[dwLen - 1] = 0;
  1578. GetPrivateProfileString("Strings", pszBuffer + 1, UNUSED_STRING, szTemp, sizeof(szTemp), pszCif);
  1579. if(lstrcmp(UNUSED_STRING, szTemp) != 0)
  1580. lstrcpyn(pszBuffer, szTemp, dwBufferSize);
  1581. else
  1582. pszBuffer[dwLen - 1] = '%';
  1583. }
  1584. }
  1585. hr = NOERROR;
  1586. }
  1587. return hr;
  1588. }
  1589. // add the quotes around the string
  1590. DWORD MyWritePrivateProfileString( LPCSTR pszSec, LPCSTR pszKey, LPCSTR pszData, LPCSTR pszFile)
  1591. {
  1592. LPSTR pszBuf;
  1593. DWORD dwOut = 0;
  1594. pszBuf = (LPSTR)LocalAlloc( LPTR, lstrlen(pszData)+8 );
  1595. if ( !pszBuf )
  1596. return dwOut;
  1597. lstrcpy( pszBuf, "\"" );
  1598. lstrcat( pszBuf, pszData );
  1599. lstrcat( pszBuf, "\"" );
  1600. dwOut = WritePrivateProfileString(pszSec, pszKey, pszBuf, pszFile);
  1601. LocalFree(pszBuf);
  1602. return dwOut;
  1603. }
  1604. HRESULT WriteTokenizeString(LPCSTR pszCif, LPCSTR pszID, LPCSTR pszTranslateKey, LPCSTR pszBuffer)
  1605. {
  1606. HRESULT hr = E_FAIL;
  1607. char szTemp[MAX_PATH];
  1608. LPCSTR pszKeyname, pszSecname;
  1609. pszKeyname = pszTranslateKey;
  1610. pszSecname = pszID;
  1611. if(GetPrivateProfileString(pszID, pszTranslateKey, "", szTemp, sizeof(szTemp), pszCif))
  1612. {
  1613. //bad code
  1614. DWORD dwLen = lstrlen(szTemp);
  1615. if(dwLen > 2)
  1616. {
  1617. // Cut the last %, and then look up in string section
  1618. if(szTemp[0] == '%' && szTemp[dwLen - 1] == '%')
  1619. {
  1620. szTemp[dwLen - 1] = 0;
  1621. pszKeyname = &szTemp[1];
  1622. pszSecname = "strings";
  1623. }
  1624. }
  1625. }
  1626. if (MyWritePrivateProfileString(pszSecname, pszKeyname, pszBuffer, pszCif))
  1627. hr = NOERROR;
  1628. return hr;
  1629. }
  1630. HWND GetVersionConflictHWND()
  1631. {
  1632. char szBuf[256];
  1633. LoadSz(IDS_VERSIONCONFLICT, szBuf, sizeof(szBuf));
  1634. HWND hVersionConflict = FindWindowEx(NULL, NULL, (LPCSTR)
  1635. SEARCHFORCONFLICT_CLASS, szBuf );
  1636. if(!hVersionConflict)
  1637. {
  1638. LoadSz(IDS_VERSIONCONFLICTNT, szBuf, sizeof(szBuf));
  1639. hVersionConflict = FindWindowEx(NULL, NULL, (LPCSTR)
  1640. SEARCHFORCONFLICT_CLASS, szBuf );
  1641. }
  1642. return hVersionConflict;
  1643. }
  1644. HRESULT WINAPI CheckForVersionConflict()
  1645. {
  1646. HWND hVersionConflict = GetVersionConflictHWND();
  1647. if(hVersionConflict)
  1648. BOOL foo = SetForegroundWindow(hVersionConflict);
  1649. return S_OK;
  1650. }
  1651. int CompareLocales(LPCSTR pcszLoc1, LPCSTR pcszLoc2)
  1652. {
  1653. int ret;
  1654. if(pcszLoc1[0] == '*' || pcszLoc2[0] == '*')
  1655. ret = 0;
  1656. else
  1657. ret = lstrcmpi(pcszLoc1, pcszLoc2);
  1658. return ret;
  1659. }
  1660. HRESULT CreateTempDirOnMaxDrive(LPSTR pszDir, DWORD dwBufSize)
  1661. {
  1662. char szRoot[] = "A:\\";
  1663. char szDownloadDrive[] = "?:\\";
  1664. char szDir[MAX_PATH];
  1665. char szUnique[MAX_PATH];
  1666. DWORD dwMaxFree = 0;
  1667. DWORD dwDriveFree;
  1668. if(pszDir)
  1669. pszDir[0] = 0;
  1670. // Check all loacle drives for diskspace and take the one with the most.
  1671. while ( szRoot[0] <= 'Z' )
  1672. {
  1673. // even the drive type is OK, verify the drive has valid connection
  1674. //
  1675. if (!IsUsableDrive( szRoot ) )
  1676. {
  1677. szRoot[0]++;
  1678. continue;
  1679. }
  1680. if(!IsDirWriteable(szRoot))
  1681. {
  1682. szRoot[0]++;
  1683. continue;
  1684. }
  1685. dwDriveFree = GetSpace(szRoot);
  1686. if (dwDriveFree > dwMaxFree)
  1687. {
  1688. dwMaxFree = dwDriveFree;
  1689. szDownloadDrive[0] = szRoot[0];
  1690. }
  1691. szRoot[0]++;
  1692. }
  1693. if(szDownloadDrive[0] == '?')
  1694. return E_FAIL;
  1695. lstrcpy(szDir, szDownloadDrive);
  1696. // if our suitable drive happens also to be the windows drive,
  1697. // create msdownld.tmp of of it.
  1698. if(szDownloadDrive[0] == g_szWindowsDir[0])
  1699. lstrcpy(szDir, g_szWindowsDir);
  1700. AddPath( szDir, MSDOWNLOAD );
  1701. if ( !IfNotExistCreateDir( szDir, TRUE, TRUE) )
  1702. return E_FAIL;
  1703. //
  1704. if ( !GetUniqueFileName(szDir,"AS", 0, szUnique) )
  1705. return E_FAIL;
  1706. lstrcpy(szDir, szUnique);
  1707. if ( !IfNotExistCreateDir( szDir, FALSE, FALSE) )
  1708. return E_FAIL;
  1709. AddPath( szDir, "" );
  1710. if ( (DWORD) lstrlen(szDir)+1 > dwBufSize )
  1711. return ( E_INVALIDARG );
  1712. // success
  1713. lstrcpy( pszDir, szDir );
  1714. return S_OK;
  1715. }
  1716. /*
  1717. * enabled or restores Sage
  1718. * bRestore TRUE means restore, otherwise disable
  1719. */
  1720. void EnableSage(BOOL bRestore)
  1721. {
  1722. //MBD 6-22: MUST USE stdcall convention when accessing sage.dll
  1723. typedef long (__stdcall *PFNDLL)(int);
  1724. HINSTANCE hSageAPI;
  1725. PFNDLL pfnSageEnable;
  1726. static int restore = ENABLE_AGENT; //initialize to valid value...
  1727. hSageAPI = LoadLibrary("SAGE.DLL");
  1728. if (hSageAPI != NULL)
  1729. {
  1730. pfnSageEnable = (PFNDLL) GetProcAddress(hSageAPI,"System_Agent_Enable");
  1731. if(pfnSageEnable)
  1732. {
  1733. if(bRestore)
  1734. {
  1735. (pfnSageEnable)(restore);
  1736. }
  1737. else
  1738. {
  1739. if(ENABLE_AGENT == (restore = (pfnSageEnable)(GET_AGENT_STATUS)))
  1740. {
  1741. (pfnSageEnable)(DISABLE_AGENT);
  1742. }
  1743. }
  1744. }
  1745. FreeLibrary(hSageAPI);
  1746. }
  1747. }
  1748. void EnableScreenSaver(BOOL bRestore)
  1749. {
  1750. static BOOL bScreenSaver = FALSE;
  1751. if (bRestore)
  1752. {
  1753. SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, bScreenSaver, 0 , 0);
  1754. bScreenSaver = FALSE; // reset the static to be able to disable the screensaver again.
  1755. }
  1756. else
  1757. {
  1758. // Only if the static is false call this again,
  1759. // otherwise we did call this function already.
  1760. if (!bScreenSaver)
  1761. {
  1762. SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, FALSE, &bScreenSaver, 0);
  1763. SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0 , 0);
  1764. }
  1765. }
  1766. }
  1767. void EnableDiskCleaner(BOOL bRestore)
  1768. {
  1769. static HANDLE hDiskCleaner = NULL;
  1770. if (bRestore)
  1771. {
  1772. if (hDiskCleaner)
  1773. {
  1774. CloseHandle(hDiskCleaner);
  1775. hDiskCleaner = NULL;
  1776. }
  1777. }
  1778. else
  1779. {
  1780. hDiskCleaner = CreateEvent(NULL, FALSE, FALSE, "DisableLowDiskWarning");
  1781. }
  1782. }
  1783. #if 0
  1784. typedef HRESULT (WINAPI *COINTERNETCREATESECURITYMANAGER) ( IServiceProvider *pSP, IInternetSecurityManager **ppSM, DWORD dwReserved);
  1785. DWORD IsUrlSaveToDownloadFrom(LPSTR lpszURL)
  1786. {
  1787. HRESULT hr;
  1788. BOOL bOK = FALSE;
  1789. DWORD dwPolicy = URLPOLICY_QUERY; // In the default case we do checktrust
  1790. HINSTANCE hUrlmon;
  1791. COINTERNETCREATESECURITYMANAGER pcicsm;
  1792. hUrlmon = LoadLibrary("urlmon.dll");
  1793. if (hUrlmon)
  1794. {
  1795. pcicsm = (COINTERNETCREATESECURITYMANAGER) GetProcAddress(hUrlmon, "CoInternetCreateSecurityManager");
  1796. if (pcicsm)
  1797. {
  1798. IInternetSecurityManager *InternetSecurityManager;
  1799. LPWSTR lpwszURL = NULL;
  1800. DWORD dwSize;
  1801. hr = pcicsm(NULL, &InternetSecurityManager, NULL);
  1802. if (SUCCEEDED(hr))
  1803. {
  1804. dwSize = sizeof(dwPolicy);
  1805. lpwszURL = MakeWideStrFromAnsi(lpszURL, STR_OLESTR);
  1806. hr = InternetSecurityManager->ProcessUrlAction(lpwszURL,
  1807. URLACTION_DOWNLOAD_SIGNED_ACTIVEX,
  1808. (BYTE*)&dwPolicy, dwSize, NULL, NULL, PUAF_NOUI, NULL);
  1809. wsprintf(szLogBuf, "InternetSecurityManager->ProcessUrlAction on :%s: Policy :%ld:", lpszURL, dwPolicy);
  1810. MessageBox(NULL, szLogBuf, "TEST", MB_OK| MB_SETFOREGROUND);
  1811. if (GetUrlPolicyPermissions(dwPolicy) != URLPOLICY_ALLOW)
  1812. {
  1813. hr = InternetSecurityManager->ProcessUrlAction(lpwszURL,
  1814. URLACTION_DOWNLOAD_UNSIGNED_ACTIVEX,
  1815. (BYTE*)&dwPolicy, dwSize, NULL, NULL, PUAF_NOUI, NULL);
  1816. wsprintf(szLogBuf, "InternetSecurityManager->ProcessUrlAction on :%s: Policy :%ld:", lpszURL, dwPolicy);
  1817. MessageBox(NULL, szLogBuf, "TEST", MB_OK| MB_SETFOREGROUND);
  1818. }
  1819. if (lpwszURL)
  1820. CoTaskMemFree(lpwszURL);
  1821. InternetSecurityManager->Release();
  1822. }
  1823. }
  1824. FreeLibrary(hUrlmon);
  1825. }
  1826. return dwPolicy;
  1827. }
  1828. #endif
  1829. BOOL PathIsFileSpec(LPCSTR lpszPath)
  1830. {
  1831. for (; *lpszPath; lpszPath = CharNext(lpszPath)) {
  1832. if (*lpszPath == '\\' || *lpszPath == ':')
  1833. return FALSE;
  1834. }
  1835. return TRUE;
  1836. }
  1837. const char c_gszRegstrPathIExplore[] = REGSTR_PATH_APPPATHS "\\iexplore.exe";
  1838. HRESULT GetIEPath(LPSTR pszPath, DWORD dwSize)
  1839. {
  1840. HRESULT hr = NOERROR;
  1841. UINT i;
  1842. DWORD dwType;
  1843. HKEY hKey;
  1844. // findout where ie is, append on cif name
  1845. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_gszRegstrPathIExplore, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
  1846. {
  1847. if ((RegQueryValueEx(hKey, NULL, 0, &dwType, (LPBYTE)pszPath, &dwSize) == ERROR_SUCCESS) &&
  1848. (dwType == REG_SZ))
  1849. {
  1850. GetParentDir(pszPath);
  1851. }
  1852. else
  1853. hr = E_INVALIDARG;
  1854. RegCloseKey(hKey);
  1855. }
  1856. else
  1857. hr = E_FAIL;
  1858. return hr;
  1859. }
  1860. DWORD MyGetFileSize(LPCSTR pszFilename)
  1861. {
  1862. DWORD dwSize;
  1863. WIN32_FIND_DATA fileData;
  1864. HANDLE hFindFile;
  1865. dwSize = 0;
  1866. hFindFile = FindFirstFile( pszFilename, &fileData );
  1867. if ( hFindFile != INVALID_HANDLE_VALUE )
  1868. {
  1869. if (fileData.nFileSizeHigh == 0)
  1870. dwSize = fileData.nFileSizeLow;
  1871. else
  1872. dwSize = (DWORD)-1;
  1873. FindClose( hFindFile );
  1874. }
  1875. return dwSize;
  1876. }
  1877. WORD GetNTProcessorArchitecture(void)
  1878. {
  1879. static WORD wNTProcArch = -1 ;
  1880. SYSTEM_INFO System_info;
  1881. // If we have calculated this before just pass that back.
  1882. // else find it now.
  1883. //
  1884. if (wNTProcArch == (WORD)-1)
  1885. {
  1886. GetSystemInfo(&System_info);
  1887. wNTProcArch = System_info.wProcessorArchitecture;
  1888. }
  1889. return wNTProcArch;
  1890. }
  1891. DWORD GetCurrentPlatform()
  1892. {
  1893. static DWORD dwPlatform = 0xffffffff;
  1894. if(dwPlatform != 0xffffffff)
  1895. return dwPlatform;
  1896. OSVERSIONINFO VerInfo;
  1897. VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1898. GetVersionEx(&VerInfo);
  1899. if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  1900. {
  1901. // Running NT
  1902. if (GetNTProcessorArchitecture() == PROCESSOR_ARCHITECTURE_ALPHA)
  1903. {
  1904. dwPlatform = PLATFORM_NT5ALPHA;
  1905. if (VerInfo.dwMajorVersion == 4)
  1906. dwPlatform = PLATFORM_NT4ALPHA;
  1907. }
  1908. else
  1909. {
  1910. dwPlatform = PLATFORM_NT5;
  1911. if (VerInfo.dwMajorVersion == 4)
  1912. dwPlatform = PLATFORM_NT4;
  1913. }
  1914. }
  1915. else
  1916. { // Running Windows 9x
  1917. dwPlatform = PLATFORM_WIN98;
  1918. if (VerInfo.dwMinorVersion == 0)
  1919. dwPlatform = PLATFORM_WIN95;
  1920. else if (VerInfo.dwMinorVersion == 90)
  1921. dwPlatform = PLATFORM_MILLEN;
  1922. }
  1923. return dwPlatform;
  1924. }
  1925. BOOL FNeedGrpConv()
  1926. {
  1927. char szSetupIni[MAX_PATH];
  1928. if(GetWindowsDirectory(szSetupIni, sizeof(szSetupIni)))
  1929. {
  1930. AddPath(szSetupIni, "setup.ini");
  1931. return(GetFileAttributes(szSetupIni) != 0xffffffff);
  1932. }
  1933. return FALSE;
  1934. }
  1935. void CopyCifString(LPCSTR pcszSect, LPCSTR pcszKey, LPCSTR pcszCifSrc, LPCSTR pcszCifDest)
  1936. {
  1937. char szField[MAX_PATH];
  1938. char szString[MAX_PATH];
  1939. LPSTR pszPercent;
  1940. if (GetPrivateProfileString(pcszSect, pcszKey, "", szField, sizeof(szField), pcszCifSrc)
  1941. && (szField[0] == '%'))
  1942. {
  1943. pszPercent = ANSIStrChr(&szField[1], '%');
  1944. if (pszPercent)
  1945. {
  1946. *pszPercent = '\0';
  1947. GetPrivateProfileString("Strings", &szField[1], "", szString, sizeof(szString), pcszCifSrc);
  1948. WritePrivateProfileString("Strings", &szField[1], szString, pcszCifDest);
  1949. }
  1950. }
  1951. }
  1952. //---------------------------------------------------------
  1953. // Function to log the Date/Time stamp for each Component.
  1954. //---------------------------------------------------------
  1955. void GetTimeDateStamp(LPSTR lpLogBuf)
  1956. {
  1957. SYSTEMTIME SystemTime;
  1958. GetLocalTime(&SystemTime);
  1959. wsprintf(lpLogBuf, "Date:%d/%d/%d (M/D/Y) Time:%d:%d:%d",
  1960. SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear,
  1961. SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
  1962. }
  1963. HRESULT WINAPI DownloadFile(LPCSTR szURL, LPCSTR szFilename, HWND hwnd, BOOL bCheckTrust, BOOL bShowBadUI)
  1964. {
  1965. HRESULT hr;
  1966. char szTempfile[MAX_PATH];
  1967. char szTemp[MAX_PATH];
  1968. CDownloader *pDL = new CDownloader();
  1969. if(!pDL)
  1970. return E_OUTOFMEMORY;
  1971. hr = pDL->SetupDownload(szURL, NULL, 0, NULL);
  1972. szTempfile[0] = 0;
  1973. if(SUCCEEDED(hr))
  1974. {
  1975. hr = pDL->DoDownload(szTempfile, sizeof(szTempfile));
  1976. }
  1977. pDL->Release();
  1978. if(SUCCEEDED(hr))
  1979. {
  1980. if (bCheckTrust)
  1981. {
  1982. hr = ::CheckTrustEx(szURL, szTempfile, bShowBadUI?hwnd:(HWND)INVALID_HANDLE_VALUE, bShowBadUI, NULL);
  1983. }
  1984. if(!CopyFile(szTempfile, szFilename, FALSE))
  1985. {
  1986. hr = HRESULT_FROM_WIN32(GetLastError());
  1987. }
  1988. }
  1989. if(szTempfile[0] != 0)
  1990. {
  1991. GetParentDir(szTempfile);
  1992. CleanUpTempDir(szTempfile);
  1993. }
  1994. return hr;
  1995. }
  1996. BOOL IsPatchableINF(LPTSTR pszInf)
  1997. {
  1998. TCHAR szBuf[MAX_PATH];
  1999. if (GetPrivateProfileInt("DefaultInstall", "Patching", 0, pszInf) ||
  2000. GetPrivateProfileString("DownloadFileSection", NULL, "", szBuf, sizeof(szBuf), pszInf))
  2001. return TRUE;
  2002. else
  2003. return FALSE;
  2004. }
  2005. PFNGETFILELIST g_pfnGetFileList = NULL;
  2006. PFNDOWNLOADANDPATCHFILES g_pfnDownloadAndPatchFiles = NULL;
  2007. PFNPROCESSFILESECTION g_pfnProcessFileSection = NULL;
  2008. BOOL InitSRLiteLibs()
  2009. {
  2010. HINSTANCE hAdvpext = LoadLibrary(c_gszAdvpext);
  2011. if (hAdvpext == NULL)
  2012. return FALSE;
  2013. g_pfnGetFileList = (PFNGETFILELIST) GetProcAddress(hAdvpext, "GetFileList");
  2014. g_pfnDownloadAndPatchFiles = (PFNDOWNLOADANDPATCHFILES) GetProcAddress(hAdvpext, "DownloadAndPatchFiles");
  2015. g_pfnProcessFileSection = (PFNPROCESSFILESECTION) GetProcAddress(hAdvpext, "ProcessFileSection");
  2016. if (g_pfnGetFileList == NULL ||
  2017. g_pfnDownloadAndPatchFiles == NULL ||
  2018. g_pfnProcessFileSection == NULL
  2019. )
  2020. {
  2021. FreeLibrary(hAdvpext);
  2022. return FALSE;
  2023. }
  2024. else
  2025. return TRUE;
  2026. }
  2027. void FreeSRLiteLibs()
  2028. {
  2029. HMODULE hMod;
  2030. hMod = GetModuleHandle(c_gszAdvpext);
  2031. if (hMod)
  2032. FreeLibrary(hMod);
  2033. }
  2034. // For now, we're patching on any IE5 version, so we might
  2035. // as well perform a check similar to ie5wzd
  2036. BOOL IsPatchableIEVersion()
  2037. {
  2038. char szIE[MAX_PATH] = { 0 };
  2039. DWORD dwMSVer, dwLSVer;
  2040. GetSystemDirectory(szIE, sizeof(szIE));
  2041. AddPath(szIE, "shdocvw.dll");
  2042. GetVersionFromFile(szIE, &dwMSVer, &dwLSVer, TRUE);
  2043. return (dwMSVer >= 0x00050000);
  2044. }
  2045. BOOL IsCorrectAdvpExt()
  2046. {
  2047. DWORD dwMSVer, dwLSVer;
  2048. GetVersionFromFile(c_gszAdvpext, &dwMSVer, &dwLSVer, TRUE);
  2049. return (dwMSVer >= 0x00050032);
  2050. }
  2051. BOOL CheckImageHlp_dll()
  2052. {
  2053. char szFile[MAX_PATH] = { 0 };
  2054. DWORD dwMSVer, dwLSVer;
  2055. GetSystemDirectory(szFile, sizeof(szFile));
  2056. AddPath(szFile, "imagehlp.dll");
  2057. GetVersionFromFile(szFile, &dwMSVer, &dwLSVer, TRUE);
  2058. return (!(dwMSVer == 0x00040000) || !(dwLSVer == 0x04C90001));
  2059. }