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.

807 lines
28 KiB

  1. #include "precomp.h"
  2. #define WM_SAVE_COMPLETE WM_USER+101
  3. extern INT_PTR CALLBACK CabSignProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
  4. extern void SignCabFile(LPCTSTR pcszFilename, LPCTSTR pcszIns, LPTSTR pszUnsignedFiles);
  5. static TCHAR s_szConfigCabName[MAX_PATH] = TEXT("");
  6. static TCHAR s_szDesktopCabName[MAX_PATH] = TEXT("");
  7. static TCHAR s_szCurrInsPath[MAX_PATH] = TEXT("");
  8. static TCHAR s_szCabsURLPath[INTERNET_MAX_URL_LENGTH] = TEXT("");
  9. static TCHAR s_szNewVersionStr[32] = TEXT("");
  10. static TCHAR s_szInsFile[MAX_PATH] = TEXT("");
  11. static INT_PTR CALLBACK displaySaveDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
  12. static BOOL doCompressCabFile(LPVOID lpVoid);
  13. static void compressCabFile();
  14. static BOOL createCab(LPCTSTR pcszCabPath, LPCTSTR pcszCabName, LPTSTR pszUnsignedFiles);
  15. static void getDefaultCabName(DWORD dwCabType, LPCTSTR pcszPrefix, LPTSTR pszCabName);
  16. static void getCabNameFromINS(LPCTSTR pcszInsFile, DWORD dwCabType, LPTSTR pszCabFullFileName, LPTSTR pszCabInfoLine = NULL);
  17. static void updateCabName(HWND hDlg, UINT nCtrlID, DWORD dwCabType, LPCTSTR pcszPrefix, LPCTSTR pcszInsFile);
  18. static BOOL makeDDFFile(LPCTSTR pcszSrcDir, LPCTSTR pcszDDF);
  19. static BOOL CanOverwriteFiles(HWND hDlg);
  20. BOOL BrowseForSave(HWND hWnd, LPTSTR szFilter, LPTSTR szFileName, int nSize, LPTSTR szDefExt)
  21. {
  22. OPENFILENAME ofn;
  23. TCHAR szDir[MAX_PATH];
  24. LPTSTR lpExt;
  25. StrCpy(szDir, szFileName);
  26. lpExt = PathFindExtension(szFileName);
  27. if (*lpExt != TEXT('\0'))
  28. {
  29. StrCpy(szFileName, PathFindFileName(szDir));
  30. PathRemoveFileSpec(szDir);
  31. }
  32. else
  33. *szFileName = TEXT('\0');
  34. ofn.lStructSize = sizeof(OPENFILENAME);
  35. ofn.hwndOwner = hWnd;
  36. ofn.hInstance = g_hUIInstance;
  37. ofn.lpstrFilter = szFilter;
  38. ofn.lpstrCustomFilter = NULL;
  39. ofn.nFilterIndex = 0;
  40. ofn.lpstrFile = szFileName;
  41. ofn.nMaxFile = nSize;
  42. ofn.lpstrFileTitle = NULL;
  43. ofn.lpstrInitialDir = szDir;
  44. ofn.lpstrTitle = NULL;
  45. ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
  46. ofn.nFileOffset = 0;
  47. ofn.nFileExtension = 0;
  48. ofn.lpstrDefExt = szDefExt;
  49. return GetSaveFileName(&ofn);
  50. }
  51. void ExportSettings()
  52. {
  53. if (PathFileExists(s_szCurrInsPath))
  54. {
  55. TCHAR szTempInsFile[MAX_PATH];
  56. TCHAR szCabInfoLine[INTERNET_MAX_URL_LENGTH + 128];
  57. // create a copy of the .INS file -> .TMP file in the temp directory
  58. GetTempPath(countof(szTempInsFile), szTempInsFile);
  59. PathAppend(szTempInsFile, TEXT("install.tmp"));
  60. CopyFile(s_szInsFile, szTempInsFile, FALSE);
  61. // save away old version sections, if any into the temp INS file
  62. if (GetPrivateProfileString(CUSTOMVERSECT, CUSTBRNDNAME, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), s_szCurrInsPath))
  63. WritePrivateProfileString(CUSTOMVERSECT, CUSTBRNDNAME, szCabInfoLine, szTempInsFile);
  64. if (GetPrivateProfileString(CUSTBRNDSECT, CUSTBRNDNAME, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), s_szCurrInsPath))
  65. WritePrivateProfileString(CUSTBRNDSECT, CUSTBRNDNAME, szCabInfoLine, szTempInsFile);
  66. if (GetPrivateProfileString(CUSTOMVERSECT, CUSTDESKNAME, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), s_szCurrInsPath))
  67. WritePrivateProfileString(CUSTOMVERSECT, CUSTDESKNAME, szCabInfoLine, szTempInsFile);
  68. if (GetPrivateProfileString(CUSTDESKSECT, CUSTDESKNAME, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), s_szCurrInsPath))
  69. WritePrivateProfileString(CUSTDESKSECT, CUSTDESKNAME, szCabInfoLine, szTempInsFile);
  70. if (GetPrivateProfileString(BRANDING, INSVERKEY, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), s_szCurrInsPath))
  71. WritePrivateProfileString(BRANDING, INSVERKEY, szCabInfoLine, szTempInsFile);
  72. // copy temp INS file to destination path
  73. CopyFile(szTempInsFile, s_szCurrInsPath, FALSE);
  74. // delete the temp INS file
  75. DeleteFile(szTempInsFile);
  76. }
  77. else
  78. {
  79. TCHAR szDir[MAX_PATH];
  80. StrCpy(szDir, s_szCurrInsPath);
  81. PathRemoveFileSpec(szDir);
  82. PathCreatePath(szDir);
  83. // copy INS file to destination path
  84. CopyFile(s_szInsFile, s_szCurrInsPath, FALSE);
  85. }
  86. DialogBox(g_hUIInstance, MAKEINTRESOURCE(IDD_DISPLAYSAVE), NULL, displaySaveDlgProc);
  87. }
  88. INT_PTR CALLBACK SaveDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  89. {
  90. TCHAR szInsFile[MAX_PATH];
  91. TCHAR szCabsURL[INTERNET_MAX_URL_LENGTH];
  92. TCHAR szPrefix[MAX_PATH];
  93. TCHAR szCabName[MAX_PATH];
  94. TCHAR szCabPath[MAX_PATH];
  95. HWND hCtrl;
  96. TCHAR szMsgText[1024];
  97. TCHAR szMsgTitle[1024];
  98. UNREFERENCED_PARAMETER(lParam);
  99. switch(uMsg)
  100. {
  101. case WM_SETFONT:
  102. //a change to mmc requires us to do this logic for all our property pages that use common controls
  103. INITCOMMONCONTROLSEX iccx;
  104. iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  105. iccx.dwICC = ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES |ICC_TREEVIEW_CLASSES;
  106. InitCommonControlsEx(&iccx);
  107. break;
  108. case WM_INITDIALOG:
  109. StrCpy(s_szInsFile, (LPCTSTR)lParam);
  110. DisableDBCSChars(hDlg, IDE_CABSURL);
  111. EnableDBCSChars(hDlg, IDE_INSFILE);
  112. EnableDBCSChars(hDlg, IDE_CAB1NAME);
  113. EnableDBCSChars(hDlg, IDE_CAB2NAME);
  114. ShowWindow(GetDlgItem(hDlg, IDC_ADVANCEDSIGN), SW_SHOW);
  115. CreateWorkDir(s_szInsFile, IEAK_GPE_BRANDING_SUBDIR, szCabPath);
  116. if (PathIsDirectoryEmpty(szCabPath))
  117. {
  118. EnableWindow(GetDlgItem(hDlg, IDC_CAB1TEXT), FALSE);
  119. EnableWindow(GetDlgItem(hDlg, IDE_CAB1NAME), FALSE);
  120. }
  121. CreateWorkDir(s_szInsFile, IEAK_GPE_DESKTOP_SUBDIR, szCabPath);
  122. if (PathIsDirectoryEmpty(szCabPath))
  123. {
  124. EnableWindow(GetDlgItem(hDlg, IDC_CAB2TEXT), FALSE);
  125. EnableWindow(GetDlgItem(hDlg, IDE_CAB2NAME), FALSE);
  126. }
  127. if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB1NAME)) &&
  128. !IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB2NAME)))
  129. {
  130. EnableWindow(GetDlgItem(hDlg, IDC_CABSURLTEXT), FALSE);
  131. EnableWindow(GetDlgItem(hDlg, IDE_CABSURL), FALSE);
  132. }
  133. //----------------- InsFile
  134. if (ISNULL(s_szCurrInsPath))
  135. {
  136. DWORD dwType = REG_SZ;
  137. DWORD dwSize = sizeof(s_szCurrInsPath);
  138. SHGetValue(HKEY_CURRENT_USER, RK_IEAK TEXT("\\SIE"), TEXT("LastOpenedFile"),
  139. &dwType, s_szCurrInsPath, &dwSize);
  140. }
  141. if (ISNONNULL(s_szCurrInsPath))
  142. {
  143. SetDlgItemText(hDlg, IDE_INSFILE, s_szCurrInsPath);
  144. GetBaseFileName(s_szCurrInsPath, szPrefix, ARRAYSIZE(szPrefix));
  145. if(StrCmpI(szPrefix, TEXT("install")) == 0)
  146. StrCpy(szPrefix, TEXT("Default"));
  147. }
  148. else
  149. *szPrefix = TEXT('\0');
  150. if (!PathFileExists(s_szCurrInsPath))
  151. {
  152. *s_szCabsURLPath = TEXT('\0');
  153. *s_szConfigCabName = TEXT('\0');
  154. *s_szDesktopCabName = TEXT('\0');
  155. *s_szNewVersionStr = TEXT('\0');
  156. }
  157. //----------------- CabsURLPath
  158. if (ISNONNULL(s_szCabsURLPath))
  159. SetDlgItemText(hDlg, IDE_CABSURL, s_szCabsURLPath);
  160. if (IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB1NAME)))
  161. {
  162. if (ISNULL(s_szConfigCabName))
  163. getDefaultCabName(CAB_TYPE_CONFIG, szPrefix, szCabName);
  164. else
  165. getDefaultCabName(CAB_TYPE_CONFIG, s_szConfigCabName, szCabName);
  166. SetDlgItemText(hDlg, IDE_CAB1NAME, szCabName);
  167. }
  168. if (IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB2NAME)))
  169. {
  170. if (ISNULL(s_szDesktopCabName))
  171. getDefaultCabName(CAB_TYPE_DESKTOP, szPrefix, szCabName);
  172. else
  173. getDefaultCabName(CAB_TYPE_DESKTOP, s_szDesktopCabName, szCabName);
  174. SetDlgItemText(hDlg, IDE_CAB2NAME, szCabName);
  175. }
  176. //----------------- Version
  177. if (ISNULL(s_szNewVersionStr))
  178. GenerateNewVersionStr(s_szCurrInsPath, s_szNewVersionStr);
  179. SetDlgItemText(hDlg, IDC_CABVERSION, s_szNewVersionStr);
  180. SetFocus(GetDlgItem(hDlg, IDE_INSFILE));
  181. return FALSE;
  182. case WM_COMMAND:
  183. switch (wParam)
  184. {
  185. case IDOK:
  186. if (GetDlgItemText(hDlg, IDE_INSFILE, szInsFile, ARRAYSIZE(szInsFile))
  187. && ((StrCmpI(PathFindExtension(szInsFile), TEXT(".ins")) == 0) ||
  188. (StrCmpI(PathFindExtension(szInsFile), TEXT(".INS")) == 0))) //looks weird, but hack is needed for turkish locale
  189. {
  190. if (IsFileCreatable(szInsFile))
  191. {
  192. *szCabsURL = TEXT('\0');
  193. if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_CABSURL)) ||
  194. (GetDlgItemText(hDlg, IDE_CABSURL, szCabsURL, ARRAYSIZE(szCabsURL))
  195. && PathIsURL(szCabsURL)))
  196. {
  197. if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB1NAME)) ||
  198. GetDlgItemText(hDlg, IDE_CAB1NAME, szCabName, ARRAYSIZE(szCabName)))
  199. {
  200. if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB2NAME)) ||
  201. GetDlgItemText(hDlg, IDE_CAB2NAME, szCabName, ARRAYSIZE(szCabName)))
  202. {
  203. if(!CanOverwriteFiles(hDlg))
  204. return TRUE;
  205. StrCpy(s_szCurrInsPath, szInsFile);
  206. StrCpy(s_szCabsURLPath, szCabsURL);
  207. GetDlgItemText(hDlg, IDE_CAB1NAME, s_szConfigCabName, ARRAYSIZE(s_szConfigCabName));
  208. GetDlgItemText(hDlg, IDE_CAB2NAME, s_szDesktopCabName, ARRAYSIZE(s_szDesktopCabName));
  209. // set the last opened INS file in the registry
  210. SHSetValue(HKEY_CURRENT_USER, RK_IEAK TEXT("\\SIE"), TEXT("LastOpenedFile"),
  211. REG_SZ, s_szCurrInsPath, sizeof(s_szCurrInsPath));
  212. EndDialog(hDlg, 0);
  213. break;
  214. }
  215. else
  216. hCtrl = GetDlgItem(hDlg, IDE_CAB2NAME);
  217. }
  218. else
  219. hCtrl = GetDlgItem(hDlg, IDE_CAB1NAME);
  220. MessageBox(hDlg, res2Str(IDS_MUSTSPECIFYNAME, szMsgText, countof(szMsgText)),\
  221. res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)), MB_OK);
  222. SendMessage(hCtrl, EM_SETSEL, 0, -1);
  223. SetFocus(hCtrl);
  224. }
  225. else
  226. {
  227. hCtrl = GetDlgItem(hDlg, IDE_CABSURL);
  228. MessageBox(hDlg, res2Str(IDS_MUSTSPECIFYURL, szMsgText, countof(szMsgText)),
  229. res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)), MB_OK);
  230. SendMessage(hCtrl, EM_SETSEL, 0, -1);
  231. SetFocus(hCtrl);
  232. }
  233. }
  234. else
  235. {
  236. MessageBox(hDlg, res2Str(IDS_CANTCREATEFILE, szMsgText, countof(szMsgText)),
  237. res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)), MB_OK);
  238. SendMessage(hCtrl = GetDlgItem(hDlg, IDE_INSFILE), EM_SETSEL, 0, -1);
  239. SetFocus(hCtrl);
  240. }
  241. }
  242. else
  243. {
  244. hCtrl = GetDlgItem(hDlg, IDE_INSFILE);
  245. MessageBox(hDlg, res2Str(IDS_MUSTSPECIFYINS, szMsgText, countof(szMsgText)),
  246. res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)), MB_OK);
  247. SendMessage(hCtrl, EM_SETSEL, 0, -1);
  248. SetFocus(hCtrl);
  249. }
  250. return TRUE;
  251. case IDCANCEL:
  252. EndDialog(hDlg, -1);
  253. break;
  254. case IDC_ADVANCEDSIGN:
  255. {
  256. PROPSHEETPAGE psp;
  257. HPROPSHEETPAGE hPage;
  258. PROPSHEETHEADER psph;
  259. psp.dwSize = sizeof(PROPSHEETPAGE);
  260. psp.dwFlags = PSP_HASHELP;
  261. psp.hInstance = g_hUIInstance;
  262. psp.pszTemplate = MAKEINTRESOURCE(IDD_CABSIGN);
  263. psp.lParam = (LPARAM)s_szInsFile;
  264. psp.pfnDlgProc = CabSignProc;
  265. hPage = CreatePropertySheetPage(&psp);
  266. ZeroMemory(&psph, sizeof(psph));
  267. psph.dwSize = sizeof(PROPSHEETHEADER);
  268. psph.hwndParent = hDlg;
  269. psph.hInstance = g_hUIInstance;
  270. psph.nPages = 1;
  271. psph.phpage = &hPage;
  272. psph.pszCaption = MAKEINTRESOURCE(IDS_CABSIGN);
  273. PropertySheet(&psph);
  274. break;
  275. }
  276. case IDC_INSBROWSE:
  277. *s_szCurrInsPath = TEXT('\0');
  278. GetDlgItemText(hDlg, IDE_INSFILE, s_szCurrInsPath, ARRAYSIZE(s_szCurrInsPath));
  279. if (BrowseForSave(hDlg, NULL, s_szCurrInsPath, ARRAYSIZE(s_szCurrInsPath), NULL))
  280. SetDlgItemText(hDlg, IDE_INSFILE, s_szCurrInsPath);
  281. //send the killfocus msg, since this is how we notice changes
  282. SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDE_INSFILE, EN_KILLFOCUS), (LPARAM)GetDlgItem(hDlg, IDE_INSFILE));
  283. return TRUE;
  284. }
  285. if (LOWORD(wParam) == IDE_INSFILE && HIWORD(wParam) == EN_KILLFOCUS &&
  286. IsWindowEnabled(GetDlgItem(hDlg, IDE_CABSURL)))
  287. {
  288. GetDlgItemText(hDlg, IDE_INSFILE, szInsFile, ARRAYSIZE(szInsFile));
  289. if(*szInsFile != TEXT('\0') && StrCmpI(PathFindExtension(szInsFile), TEXT(".ins")) == 0)
  290. {
  291. GetBaseFileName(szInsFile, szPrefix, ARRAYSIZE(szPrefix));
  292. if(StrCmpI(szPrefix, TEXT("install")) == 0)
  293. StrCpy(szPrefix, TEXT("Default"));
  294. GetPrivateProfileString(BRANDING, CABSURLPATH, TEXT(""), szCabsURL,
  295. countof(szCabsURL), szInsFile);
  296. if (ISNONNULL(szCabsURL))
  297. SetDlgItemText(hDlg, IDE_CABSURL, szCabsURL);
  298. if (IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB1NAME)))
  299. updateCabName(hDlg, IDE_CAB1NAME, CAB_TYPE_CONFIG, szPrefix, szInsFile);
  300. if (IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB2NAME)))
  301. updateCabName(hDlg, IDE_CAB2NAME, CAB_TYPE_DESKTOP, szPrefix, szInsFile);
  302. }
  303. }
  304. break;
  305. }
  306. return FALSE;
  307. }
  308. static INT_PTR CALLBACK displaySaveDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  309. {
  310. static HANDLE s_hThread;
  311. DWORD dwThread;
  312. TCHAR szMsgTitle[1024];
  313. UNREFERENCED_PARAMETER(wParam);
  314. UNREFERENCED_PARAMETER(lParam);
  315. switch( msg )
  316. {
  317. case WM_INITDIALOG:
  318. SetWindowText(hDlg, res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)));
  319. Animate_Open( GetDlgItem( hDlg, IDC_ANIMATE ), IDA_GEARS );
  320. Animate_Play( GetDlgItem( hDlg, IDC_ANIMATE ), 0, -1, -1 );
  321. if((s_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) doCompressCabFile, (LPVOID) hDlg, 0, &dwThread)) == NULL)
  322. {
  323. compressCabFile();
  324. EndDialog(hDlg, 1);
  325. }
  326. break;
  327. case WM_SAVE_COMPLETE:
  328. EndDialog(hDlg, 1);
  329. break;
  330. case WM_DESTROY:
  331. if (s_hThread != NULL)
  332. CloseHandle(s_hThread);
  333. break;
  334. default:
  335. return 0;
  336. }
  337. return 1;
  338. }
  339. static BOOL doCompressCabFile(LPVOID lpVoid)
  340. {
  341. HWND hDlg = (HWND) lpVoid;
  342. compressCabFile();
  343. PostMessage(hDlg, WM_SAVE_COMPLETE, 0, 0L);
  344. return TRUE;
  345. }
  346. static void compressCabFile()
  347. {
  348. TCHAR szCabPath[MAX_PATH];
  349. TCHAR szType[8];
  350. TCHAR szUnsignedFiles[MAX_PATH * 2] = TEXT("");
  351. //-------------------- Config
  352. CreateWorkDir(s_szInsFile, IEAK_GPE_BRANDING_SUBDIR, szCabPath);
  353. if (createCab(szCabPath, s_szConfigCabName, szUnsignedFiles))
  354. SetOrClearVersionInfo(s_szCurrInsPath, CAB_TYPE_CONFIG, s_szConfigCabName,
  355. s_szCabsURLPath, s_szNewVersionStr, SET);
  356. else
  357. SetOrClearVersionInfo(s_szCurrInsPath, CAB_TYPE_CONFIG, s_szConfigCabName,
  358. s_szCabsURLPath, s_szNewVersionStr, CLEAR);
  359. //-------------------- Desktop
  360. CreateWorkDir(s_szInsFile, IEAK_GPE_DESKTOP_SUBDIR, szCabPath);
  361. if (createCab(szCabPath, s_szDesktopCabName, szUnsignedFiles))
  362. SetOrClearVersionInfo(s_szCurrInsPath, CAB_TYPE_DESKTOP, s_szDesktopCabName,
  363. s_szCabsURLPath, s_szNewVersionStr, SET);
  364. else
  365. SetOrClearVersionInfo(s_szCurrInsPath, CAB_TYPE_DESKTOP, s_szDesktopCabName,
  366. s_szCabsURLPath, s_szNewVersionStr, CLEAR);
  367. WritePrivateProfileString(BRANDING, CABSURLPATH, s_szCabsURLPath, s_szCurrInsPath);
  368. WritePrivateProfileString(BRANDING, INSVERKEY, s_szNewVersionStr, s_szCurrInsPath);
  369. // write the type as INTRANET so that the branding DLL extracts and processes the cabs in the CUSTOM dir
  370. wnsprintf(szType, countof(szType), TEXT("%u"), INTRANET);
  371. WritePrivateProfileString(BRANDING, TEXT("Type"), szType, s_szCurrInsPath);
  372. if (ISNONNULL(szUnsignedFiles))
  373. {
  374. TCHAR szMessage[MAX_PATH*3];
  375. TCHAR szMsg[64];
  376. LoadString(g_hUIInstance, IDS_CABSIGN_ERROR, szMsg, ARRAYSIZE(szMsg));
  377. wnsprintf(szMessage, ARRAYSIZE(szMessage), szMsg, szUnsignedFiles);
  378. MessageBox(NULL, szMessage, TEXT(""), MB_OK | MB_SETFOREGROUND);
  379. }
  380. }
  381. static BOOL createCab(LPCTSTR pcszCabPath, LPCTSTR pcszCabName, LPTSTR pszUnsignedFiles)
  382. {
  383. TCHAR szCmd[MAX_PATH*4];
  384. TCHAR szDest[MAX_PATH];
  385. TCHAR szDDF[MAX_PATH];
  386. TCHAR szTempPath[MAX_PATH];
  387. if (!PathFileExists(pcszCabPath) || PathIsDirectoryEmpty(pcszCabPath))
  388. return FALSE;
  389. // create a temporary cab folder
  390. GetTempPath(countof(szTempPath), szTempPath);
  391. PathAppend(szTempPath, TEXT("SIE"));
  392. PathCreatePath(szTempPath);
  393. PathCombine(szDDF, szTempPath, TEXT("folder.ddf"));
  394. if (!makeDDFFile(pcszCabPath, szDDF))
  395. return FALSE;
  396. wnsprintf(szCmd, countof(szCmd),
  397. TEXT("MAKECAB.EXE /D CabinetName1=\"%s\" /D DiskDirectory1=\"%s\" /F %s"),
  398. pcszCabName, szTempPath, szDDF);
  399. RunAndWait(szCmd, szTempPath, SW_HIDE);
  400. // if the cab file exist in the destination path set the attribute to normal
  401. StrCpy(szDest, s_szCurrInsPath);
  402. PathRemoveFileSpec(szDest);
  403. PathAppend(szDest, pcszCabName);
  404. if (PathFileExists(szDest))
  405. SetFileAttributes(szDest, FILE_ATTRIBUTE_NORMAL);
  406. PathAppend(szTempPath, pcszCabName);
  407. CopyFile(szTempPath, szDest, FALSE);
  408. SignCabFile(szDest, s_szCurrInsPath, pszUnsignedFiles);
  409. // remove the temporary folder
  410. PathRemovePath(szDDF);
  411. return TRUE;
  412. }
  413. static void getDefaultCabName(DWORD dwCabType, LPCTSTR pcszPrefix, LPTSTR pszCabName)
  414. {
  415. TCHAR szActualPrefix[MAX_PATH];
  416. *pszCabName = TEXT('\0');
  417. if (pcszPrefix == NULL || *pcszPrefix == TEXT('\0'))
  418. return;
  419. if (StrChr(pcszPrefix, '.') != NULL)
  420. {
  421. StrCpy(pszCabName, pcszPrefix);
  422. return;
  423. }
  424. StrCpy(szActualPrefix, pcszPrefix);
  425. switch(dwCabType)
  426. {
  427. case CAB_TYPE_CONFIG:
  428. wnsprintf(pszCabName, MAX_PATH, TEXT("%s_config.cab"), szActualPrefix);
  429. break;
  430. case CAB_TYPE_DESKTOP:
  431. wnsprintf(pszCabName, MAX_PATH, TEXT("%s_desktop.cab"), szActualPrefix);
  432. break;
  433. }
  434. }
  435. static void getCabNameFromINS(LPCTSTR pcszInsFile, DWORD dwCabType, LPTSTR pszCabFullFileName, LPTSTR pszCabInfoLine /* = NULL*/)
  436. {
  437. LPCTSTR pcszSection = NULL, pcszKey = NULL;
  438. TCHAR szCabFilePath[MAX_PATH];
  439. TCHAR szCabName[MAX_PATH];
  440. TCHAR szCabInfoLine[INTERNET_MAX_URL_LENGTH + 128];
  441. if (pcszInsFile == NULL || *pcszInsFile == TEXT('\0') || pszCabFullFileName == NULL)
  442. return;
  443. *pszCabFullFileName = TEXT('\0');
  444. if (pszCabInfoLine != NULL)
  445. *pszCabInfoLine = TEXT('\0');
  446. switch (dwCabType)
  447. {
  448. case CAB_TYPE_CONFIG:
  449. pcszSection = CUSTBRNDSECT;
  450. pcszKey = CUSTBRNDNAME;
  451. break;
  452. case CAB_TYPE_DESKTOP:
  453. pcszSection = CUSTDESKSECT;
  454. pcszKey = CUSTDESKNAME;
  455. break;
  456. }
  457. if (pcszSection == NULL || pcszKey == NULL)
  458. return;
  459. StrCpy(szCabFilePath, pcszInsFile);
  460. PathRemoveFileSpec(szCabFilePath);
  461. if (GetPrivateProfileString(pcszSection, pcszKey, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), pcszInsFile) == 0)
  462. GetPrivateProfileString(CUSTOMVERSECT, pcszKey, TEXT(""), szCabInfoLine, ARRAYSIZE(szCabInfoLine), pcszInsFile);
  463. if (*szCabInfoLine)
  464. {
  465. LPTSTR pszT;
  466. if ((pszT = StrChr(szCabInfoLine, TEXT(','))) != NULL)
  467. *pszT = TEXT('\0');
  468. if ((pszT = PathFindFileName(szCabInfoLine)) > szCabInfoLine)
  469. {
  470. // cab URL path is specified
  471. *(pszT - 1) = TEXT('\0'); // nul the '/' char
  472. }
  473. StrCpy(szCabName, pszT);
  474. PathCombine(pszCabFullFileName, szCabFilePath, szCabName);
  475. if (pszCabInfoLine)
  476. StrCpy(pszCabInfoLine, szCabInfoLine);
  477. }
  478. }
  479. static void updateCabName(HWND hDlg, UINT nCtrlID, DWORD dwCabType, LPCTSTR pcszPrefix, LPCTSTR pcszInsFile)
  480. {
  481. TCHAR szTempCabName[MAX_PATH];
  482. BOOL fCabName = FALSE;
  483. *szTempCabName = TEXT('\0');
  484. if (PathFileExists(pcszInsFile))
  485. {
  486. getCabNameFromINS(pcszInsFile, dwCabType, szTempCabName);
  487. if (ISNONNULL(szTempCabName))
  488. {
  489. SetDlgItemText(hDlg, nCtrlID, PathFindFileName(szTempCabName));
  490. fCabName = TRUE;
  491. }
  492. }
  493. else
  494. GetDlgItemText(hDlg, nCtrlID, szTempCabName, countof(szTempCabName));
  495. if (!fCabName)
  496. {
  497. TCHAR szCabSuffix[MAX_PATH];
  498. TCHAR szCabName[MAX_PATH];
  499. if (dwCabType == CAB_TYPE_CONFIG)
  500. StrCpy(szCabSuffix, TEXT("_config.cab"));
  501. else if (dwCabType == CAB_TYPE_DESKTOP)
  502. StrCpy(szCabSuffix, TEXT("_desktop.cab"));
  503. if (ISNULL(szTempCabName) || StrStrI(szTempCabName, szCabSuffix) != NULL)
  504. {
  505. getDefaultCabName(dwCabType, pcszPrefix, szCabName);
  506. SetDlgItemText(hDlg, nCtrlID, szCabName);
  507. }
  508. }
  509. }
  510. #define BUFFER_SIZE 1024
  511. HRESULT pepFileEnumProc(LPCTSTR pszPath, PWIN32_FIND_DATA pfd, LPARAM lParam, PDWORD *prgdwControl /*= NULL*/)
  512. {
  513. LPTSTR pListBuffer = NULL;
  514. static DWORD s_dwBuffer = 0;
  515. DWORD dwLen;
  516. UNREFERENCED_PARAMETER(prgdwControl);
  517. ASSERT(pszPath != NULL && pfd != NULL && lParam != NULL);
  518. // if its is a directory name, we have nothing to do with it
  519. if (pfd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  520. return S_OK;
  521. pListBuffer = *((LPTSTR*)lParam);
  522. if (pListBuffer == NULL) // allocate buffer for the first time
  523. {
  524. s_dwBuffer = BUFFER_SIZE;
  525. pListBuffer = (LPTSTR)CoTaskMemAlloc(s_dwBuffer);
  526. if (pListBuffer == NULL)
  527. return E_OUTOFMEMORY;
  528. *((LPTSTR*)lParam) = pListBuffer;
  529. ZeroMemory(pListBuffer, s_dwBuffer);
  530. }
  531. // if not enough memory reallocate
  532. // StrCbFromSz adds 1 extra unit, accounting 2 units for double quotes,
  533. // add 3 extra unit for the \r\n and the NULL character
  534. if (StrCbFromSz(pListBuffer) + StrCbFromSz(pszPath) + StrCbFromCch(3) > s_dwBuffer)
  535. {
  536. LPVOID lpTemp;
  537. s_dwBuffer += BUFFER_SIZE;
  538. lpTemp = CoTaskMemRealloc(pListBuffer, s_dwBuffer);
  539. if (lpTemp == NULL)
  540. return E_OUTOFMEMORY;
  541. pListBuffer = (LPTSTR)lpTemp;
  542. *((LPTSTR*)lParam) = pListBuffer;
  543. ZeroMemory(pListBuffer + StrCchFromCb(s_dwBuffer - BUFFER_SIZE), BUFFER_SIZE);
  544. }
  545. // append the string to buffer
  546. dwLen = StrLen(pListBuffer);
  547. wnsprintf(pListBuffer + dwLen, StrCchFromCb(s_dwBuffer) - dwLen , TEXT("\"%s\"\r\n"), pszPath);
  548. return S_OK;
  549. }
  550. static BOOL makeDDFFile(LPCTSTR pcszSrcDir, LPCTSTR pcszDDF)
  551. {
  552. HANDLE hDDF;
  553. LPTSTR pFileList = NULL;
  554. BOOL fRetVal = FALSE;
  555. HRESULT hrResult;
  556. hDDF = CreateFile(pcszDDF, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  557. FILE_ATTRIBUTE_NORMAL, NULL);
  558. if (hDDF == INVALID_HANDLE_VALUE)
  559. return fRetVal;
  560. hrResult = PathEnumeratePath(pcszSrcDir, PEP_DEFAULT,
  561. pepFileEnumProc, (LPARAM)&pFileList);
  562. if (pFileList != NULL)
  563. {
  564. TCHAR szMsgText[1024];
  565. TCHAR szMsgTitle[1024];
  566. if (hrResult == S_OK)
  567. fRetVal = WriteStringToFile(hDDF, pFileList, StrLen(pFileList));
  568. else if (hrResult == E_OUTOFMEMORY)
  569. MessageBox(NULL, res2Str(IDS_MEMORY_ERROR, szMsgText, countof(szMsgText)),
  570. res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)), MB_OK);
  571. CoTaskMemFree(pFileList);
  572. }
  573. CloseHandle(hDDF);
  574. return fRetVal;
  575. }
  576. static BOOL CanOverwriteFiles(HWND hDlg)
  577. {
  578. TCHAR szExistingFiles[MAX_PATH*5];
  579. TCHAR szTemp[MAX_PATH];
  580. TCHAR szDir[MAX_PATH];
  581. TCHAR szFile[MAX_PATH];
  582. TCHAR szReadOnlyFiles[MAX_PATH*5];
  583. *szExistingFiles = TEXT('\0');
  584. *szReadOnlyFiles = TEXT('\0');
  585. // check for file already exists in the destination directory.
  586. GetDlgItemText(hDlg, IDE_INSFILE, szTemp, ARRAYSIZE(szTemp));
  587. if (PathFileExists(szTemp))
  588. {
  589. StrCat(szExistingFiles, szTemp);
  590. StrCat(szExistingFiles, TEXT("\r\n"));
  591. if (IsFileReadOnly(szTemp))
  592. StrCpy(szReadOnlyFiles, szExistingFiles);
  593. }
  594. StrCpy(szDir, szTemp);
  595. PathRemoveFileSpec(szDir);
  596. if (IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB1NAME)))
  597. {
  598. GetDlgItemText(hDlg, IDE_CAB1NAME, szTemp, ARRAYSIZE(szTemp));
  599. PathCombine(szFile, szDir, szTemp);
  600. if (PathFileExists(szFile))
  601. {
  602. StrCat(szExistingFiles, szFile);
  603. StrCat(szExistingFiles, TEXT("\r\n"));
  604. if (IsFileReadOnly(szFile))
  605. {
  606. StrCat(szReadOnlyFiles, szFile);
  607. StrCat(szReadOnlyFiles, TEXT("\r\n"));
  608. }
  609. }
  610. }
  611. if (IsWindowEnabled(GetDlgItem(hDlg, IDE_CAB2NAME)))
  612. {
  613. GetDlgItemText(hDlg, IDE_CAB2NAME, szTemp, ARRAYSIZE(szTemp));
  614. PathCombine(szFile, szDir, szTemp);
  615. if (PathFileExists(szFile))
  616. {
  617. StrCat(szExistingFiles, szFile);
  618. StrCat(szExistingFiles, TEXT("\r\n"));
  619. if (IsFileReadOnly(szFile))
  620. {
  621. StrCat(szReadOnlyFiles, szFile);
  622. StrCat(szReadOnlyFiles, TEXT("\r\n"));
  623. }
  624. }
  625. }
  626. if (*szReadOnlyFiles != TEXT('\0'))
  627. {
  628. TCHAR szMsg[MAX_PATH*6];
  629. TCHAR szMsgText[MAX_PATH];
  630. TCHAR szMsgTitle[MAX_PATH];
  631. wnsprintf(szMsg, countof(szMsg), res2Str(IDS_FILE_READONLY, szMsgText, countof(szMsgText)), szReadOnlyFiles);
  632. MessageBox(hDlg, szMsg, res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)), MB_ICONEXCLAMATION | MB_OK);
  633. return FALSE;
  634. }
  635. if (*szExistingFiles != TEXT('\0'))
  636. {
  637. TCHAR szMsg[MAX_PATH*6];
  638. TCHAR szMsgText[MAX_PATH];
  639. TCHAR szMsgTitle[MAX_PATH];
  640. wnsprintf(szMsg, countof(szMsg), res2Str(IDS_FILE_ALREADY_EXISTS, szMsgText, countof(szMsgText)), szExistingFiles);
  641. if (MessageBox(hDlg, szMsg, res2Str(IDS_TITLE, szMsgTitle, countof(szMsgTitle)),
  642. MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2) == IDNO)
  643. return FALSE;
  644. }
  645. return TRUE;
  646. }