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.

720 lines
22 KiB

  1. #include "privcpp.h"
  2. #include "shlwapi.h"
  3. extern HINSTANCE g_hinst;
  4. // This list needs to continue to be updated and we should try to keep parity with Office
  5. const LPCTSTR c_arszUnsafeExts[] =
  6. {TEXT(".exe"), TEXT(".com"), TEXT(".bat"), TEXT(".lnk"), TEXT(".url"),
  7. TEXT(".cmd"), TEXT(".inf"), TEXT(".reg"), TEXT(".isp"), TEXT(".bas"), TEXT(".pcd"),
  8. TEXT(".mst"), TEXT(".pif"), TEXT(".scr"), TEXT(".hlp"), TEXT(".chm"), TEXT(".hta"), TEXT(".asp"),
  9. TEXT(".js"), TEXT(".jse"), TEXT(".vbs"), TEXT(".vbe"), TEXT(".ws"), TEXT(".wsh"), TEXT(".msi"),
  10. TEXT(".ade"), TEXT(".adp"), TEXT(".crt"), TEXT(".ins"), TEXT(".mdb"),
  11. TEXT(".mde"), TEXT(".msc"), TEXT(".msp"), TEXT(".sct"), TEXT(".shb"),
  12. TEXT(".vb"), TEXT(".wsc"), TEXT(".wsf"), TEXT(".cpl"), TEXT(".shs"),
  13. TEXT(".vsd"), TEXT(".vst"), TEXT(".vss"), TEXT(".vsw"), TEXT(".its"), TEXT(".tmp"),
  14. TEXT(".mdw"), TEXT(".mdt"), TEXT(".ops")
  15. };
  16. const LPCTSTR c_arszExecutableExtns[] =
  17. {TEXT(".exe"), TEXT(".com"), TEXT(".bat"), TEXT(".lnk"), TEXT(".cmd"), TEXT(".pif"),
  18. TEXT(".scr"), TEXT(".js"), TEXT(".jse"), TEXT(".vbs"), TEXT(".vbe"), TEXT(".wsh"),
  19. TEXT(".sct"), TEXT(".vb"), TEXT(".wsc"), TEXT(".wsf")
  20. };
  21. BOOL IsProgIDInList(LPCTSTR pszProgID, LPCTSTR pszExt, const LPCTSTR *arszList, UINT nExt)
  22. {
  23. TCHAR szClassName[MAX_PATH];
  24. DWORD cbSize = SIZEOF(szClassName);
  25. if ((!pszProgID || !*pszProgID) && (!pszExt || !*pszExt))
  26. return FALSE;
  27. if (!pszProgID || !*pszProgID)
  28. {
  29. if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, pszExt, NULL, NULL, szClassName, &cbSize))
  30. pszProgID = szClassName;
  31. else
  32. pszProgID = NULL;
  33. }
  34. for (UINT n = 0; n < nExt; n++)
  35. {
  36. // check extension if available
  37. if (pszExt && (0 == StrCmpI(pszExt, arszList[n])))
  38. return TRUE;
  39. if (!pszProgID) // no progid available, just check the extension
  40. continue;
  41. DWORD dwValueType;
  42. TCHAR szTempID[MAX_PATH];
  43. szTempID[0] = TEXT('\0');
  44. ULONG cb = ARRAYSIZE(szTempID)*sizeof(TCHAR);
  45. if (ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT, arszList[n], NULL, &dwValueType, (PBYTE)szTempID, &cb))
  46. if (!StrCmpI(pszProgID, szTempID))
  47. return TRUE;
  48. }
  49. return FALSE;
  50. }
  51. //////////////////////////////////////////////////////////////////////
  52. //
  53. // Icon Helper Functions
  54. //
  55. //////////////////////////////////////////////////////////////////////
  56. void CPackage::_CreateSaferIconTitle(LPTSTR szSaferTitle, LPCTSTR szIconText)
  57. {
  58. // Note: szSaferTitle must be at least MAX_PATH. In theory the szIconText could be MAX_PATH, and
  59. // the real file name could also be MAX_PATH. However, since this is just trying to be "safer",
  60. // and anything even approaching MAX_PATH in length would be very, very, strange (and would look that way to the user)
  61. // we are just assuming MAX_PATH. Anything greater will be truncated.
  62. #ifdef USE_RESOURCE_DLL
  63. HINSTANCE hInstRes = LoadLibraryEx(L"sp1res.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
  64. if(!hInstRes)
  65. return ;
  66. #endif
  67. WCHAR szTemp[MAX_PATH];
  68. if(CMDLINK == _panetype)
  69. {
  70. // As a security we display the words "(Command Line)" in the title
  71. WCHAR szCommandLine[80];
  72. WCHAR szFormat[20];
  73. LoadString(hInstRes, IDS_COMMAND_LINE, szCommandLine, ARRAYSIZE(szCommandLine));
  74. LoadString(hInstRes, IDS_ICON_COMMAND_LINE_FORMAT, szFormat, ARRAYSIZE(szFormat));
  75. // I don't want to muck with the szIconText so using szTemp
  76. // Limited to 80 so we can be sure of seeing the (.exe) or whatever
  77. StringCchCopy(szTemp, 80, szIconText);
  78. LPTSTR args[3];
  79. args[0] = (LPTSTR) szTemp;
  80. args[1] = szCommandLine;
  81. args[2] = NULL;
  82. if(! FormatMessage(
  83. FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  84. szFormat,
  85. 0,
  86. 0, // Default language
  87. szSaferTitle,
  88. MAX_PATH,
  89. (va_list *) args
  90. ))
  91. {
  92. StringCchCopy(szSaferTitle, MAX_PATH, szIconText);
  93. }
  94. }
  95. else if(_pEmbed && *_pEmbed->fd.cFileName)
  96. {
  97. LPTSTR szExtLabel;
  98. LPTSTR szExtFile;
  99. szExtLabel = PathFindExtension(szIconText);
  100. szExtFile = PathFindExtension(_pEmbed->fd.cFileName);
  101. if(szExtFile && *szExtFile && lstrcmpi(szExtFile, szExtLabel) != 0)
  102. {
  103. // I don't want to muck with the szIconText so using szTemp
  104. // Limited to 60 so we can be sure of seeing the (.exe) or whatever
  105. StringCchCopy(szTemp, 80, szIconText);
  106. LPTSTR args[3];
  107. args[0] = (LPTSTR) szTemp;
  108. args[1] = szExtFile;
  109. args[2] = NULL;
  110. // As a security we display the truefileName + trueExt in ()
  111. WCHAR szFormat[20];
  112. LoadString(hInstRes, IDS_ICON_TITLE_FORMAT, szFormat, ARRAYSIZE(szFormat));
  113. if(! FormatMessage(
  114. FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  115. szFormat,
  116. 0,
  117. 0, // Default language
  118. szSaferTitle,
  119. MAX_PATH,
  120. (va_list *) args
  121. ))
  122. {
  123. StringCchCopy(szSaferTitle, MAX_PATH, szIconText);
  124. }
  125. }
  126. else
  127. StringCchCopy(szSaferTitle, MAX_PATH, szIconText);
  128. }
  129. else
  130. StringCchCopy(szSaferTitle, MAX_PATH, szIconText);
  131. #ifdef USE_RESOURCE_DLL
  132. FreeLibrary(hInstRes);
  133. #endif
  134. }
  135. void CPackage::_IconDraw(LPIC lpic, HDC hdc, LPRECT lprc)
  136. {
  137. //
  138. // draw's the icon and the text to the specfied DC in the given
  139. // bounding rect.
  140. //
  141. // Visual Basic calls us with a NULL lprc
  142. // It's a bit hoaky but for now we'll just make a rect the same size as the icon
  143. RECT aFakeRect;
  144. if(!lprc)
  145. {
  146. aFakeRect.top = 0;
  147. aFakeRect.left = 0;
  148. aFakeRect.bottom = lpic->rc.bottom + 1;
  149. aFakeRect.right = lpic->rc.right + 1;
  150. lprc = &aFakeRect;
  151. }
  152. DebugMsg(DM_TRACE, "pack - IconDraw() called.");
  153. DebugMsg(DM_TRACE, " left==%d,top==%d,right==%d,bottom==%d",
  154. lprc->left,lprc->top,lprc->right,lprc->bottom);
  155. // make sure we'll fit in the given rect
  156. //comment out for now -- if fixes a MS Project bug (rect is 1 pixel too short). If it creates more problems we'll take another look
  157. //if (((lpic->rc.right-lpic->rc.left) > (lprc->right - lprc->left)) ||
  158. // ((lpic->rc.bottom-lpic->rc.top) > (lprc->bottom - lprc->top)))
  159. // return;
  160. // Draw the icon
  161. if (lpic->hDlgIcon)
  162. {
  163. DrawIcon(hdc, (lprc->left + lprc->right - g_cxIcon) / 2,
  164. (lprc->top + lprc->bottom - lpic->rc.bottom) / 2, lpic->hDlgIcon);
  165. }
  166. WCHAR szLabel[MAX_PATH];
  167. _CreateSaferIconTitle(szLabel, lpic->szIconText);
  168. if (*szLabel)
  169. {
  170. HFONT hfont = SelectFont(hdc, g_hfontTitle);
  171. RECT rcText;
  172. rcText.left = lprc->left;
  173. rcText.right = lprc->right;
  174. rcText.top = (lprc->top + lprc->bottom - lpic->rc.bottom) / 2 + g_cyIcon + 1;
  175. rcText.bottom = lprc->bottom;
  176. DrawText(hdc, szLabel, -1, &rcText, DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_SINGLELINE | DT_TOP);
  177. if (hfont)
  178. SelectObject(hdc, hfont);
  179. }
  180. }
  181. LPIC IconCreate(void)
  182. {
  183. //
  184. // allocates space for our icon structure which holds icon index,
  185. // the icon path, the handle to the icon, and the icon text
  186. // return: NULL on failure
  187. // a valid pointer on success
  188. //
  189. DebugMsg(DM_TRACE, "pack - IconCreate() called.");
  190. // Allocate memory for the IC structure
  191. return (LPIC)GlobalAlloc(GPTR, sizeof(IC));
  192. }
  193. LPIC CPackage::_IconCreateFromFile(LPCTSTR lpstrFile)
  194. {
  195. //
  196. // initializes an IC structure (defined in pack2.h) from a given
  197. // filename.
  198. // return: NULL on failure
  199. // a valid pointer on success
  200. //
  201. LPIC lpic;
  202. DebugMsg(DM_TRACE, "pack - IconCreateFromFile() called.");
  203. if (lpic = IconCreate())
  204. {
  205. // Get the icon
  206. StringCchCopy(lpic->szIconPath, ARRAYSIZE(lpic->szIconPath), lpstrFile);
  207. lpic->iDlgIcon = 0;
  208. if (*(lpic->szIconPath))
  209. _GetCurrentIcon(lpic);
  210. // Get the icon text -- calls ILGetDisplayName
  211. //
  212. GetDisplayName(lpic->szIconText, lpstrFile);
  213. if (!_IconCalcSize(lpic))
  214. {
  215. if (lpic->hDlgIcon)
  216. DestroyIcon(lpic->hDlgIcon);
  217. GlobalFree(lpic);
  218. lpic = NULL;
  219. }
  220. }
  221. return lpic;
  222. }
  223. BOOL CPackage::_IconCalcSize(LPIC lpic)
  224. {
  225. HDC hdcWnd;
  226. RECT rcText = { 0 };
  227. SIZE Image;
  228. HFONT hfont;
  229. DebugMsg(DM_TRACE, "pack - IconCalcSize called.");
  230. // get the window DC, and make a DC compatible to it
  231. if (!(hdcWnd = GetDC(NULL))) {
  232. DebugMsg(DM_TRACE, " couldn't get DC!!");
  233. return FALSE;
  234. }
  235. ASSERT(lpic);
  236. WCHAR szLabel[MAX_PATH];
  237. _CreateSaferIconTitle(szLabel, lpic->szIconText);
  238. if (*szLabel)
  239. {
  240. SetRect(&rcText, 0, 0, g_cxArrange, g_cyArrange);
  241. // Set the icon text rectangle, and the icon font
  242. hfont = SelectFont(hdcWnd, g_hfontTitle);
  243. // Figure out how large the text region will be
  244. rcText.bottom = DrawText(hdcWnd, szLabel, -1, &rcText,
  245. DT_CALCRECT | DT_WORDBREAK | DT_NOPREFIX | DT_SINGLELINE);
  246. if (hfont)
  247. SelectObject(hdcWnd, hfont);
  248. }
  249. // Compute the image size
  250. rcText.right++;
  251. Image.cx = (rcText.right > g_cxIcon) ? rcText.right : g_cxIcon;
  252. Image.cy = g_cyIcon + rcText.bottom + 1;
  253. // grow the image a bit
  254. Image.cx += Image.cx / 4;
  255. Image.cy += Image.cy / 8;
  256. lpic->rc.right = Image.cx;
  257. lpic->rc.bottom = Image.cy;
  258. DebugMsg(DM_TRACE," lpic->rc.right==%d,lpic->rc.bottom==%d",
  259. lpic->rc.right,lpic->rc.bottom);
  260. return TRUE;
  261. }
  262. void CPackage::_GetCurrentIcon(LPIC lpic)
  263. {
  264. #ifdef USE_RESOURCE_DLL
  265. HINSTANCE hInstRes = LoadLibraryEx(L"sp1res.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
  266. if(!hInstRes)
  267. return;
  268. #endif
  269. WORD wIcon = (WORD)lpic->iDlgIcon;
  270. DebugMsg(DM_TRACE, "pack - GetCurrentIcon() called.");
  271. if (lpic->hDlgIcon)
  272. DestroyIcon(lpic->hDlgIcon);
  273. SHFILEINFO shInfo;
  274. // Check to see if we can get an icon from the specified path
  275. // SECURITY!!
  276. // SHGFI_USEFILEATTRIBUTES will get the icon for the this ext.
  277. // We just want to use this icon for files we THINK may be, possibly, could be, should be, we
  278. // hope are SAFE. We'll use some "scary" icon for files that are potentially dangerous
  279. LPTSTR szIconFileName;
  280. if(_pEmbed && *_pEmbed->fd.cFileName)
  281. {
  282. szIconFileName = _pEmbed->fd.cFileName;
  283. }
  284. else
  285. {
  286. szIconFileName = lpic->szIconPath;
  287. }
  288. // LPTSTR szExt = PathFindExtension(lpic->szIconText);
  289. LPTSTR szExt = PathFindExtension(szIconFileName);
  290. if(CMDLINK == _panetype)
  291. {
  292. // If it's a command line package, it always gets the warning icon
  293. lpic->hDlgIcon = (HICON)LoadImage(hInstRes, MAKEINTRESOURCE(IDI_PACKAGE_WARNING),
  294. IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
  295. }
  296. else if(szExt && *szExt)
  297. {
  298. // If it's in our list of dangerous ext, then use the "scary" icon
  299. // For now I'm using the "executable" list to avoid crying wolf too often
  300. // we may want to re-visit and use c_arszUnsafeExts
  301. if(IsProgIDInList(NULL, szExt, c_arszExecutableExtns, ARRAYSIZE(c_arszExecutableExtns)))
  302. {
  303. shInfo.hIcon = (HICON)LoadImage(hInstRes, MAKEINTRESOURCE(IDI_PACKAGE_WARNING),
  304. IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
  305. }
  306. else
  307. {
  308. // No, not scary, then just use the icon associated with the ext
  309. if(!SHGetFileInfo(szExt,
  310. FILE_ATTRIBUTE_NORMAL,
  311. &shInfo,
  312. sizeof(SHFILEINFO),
  313. SHGFI_ICON | SHGFI_USEFILEATTRIBUTES))
  314. {
  315. // OK, that still didn't work, so it's an unrecognized ext.
  316. // In that case we'll go back and use the warning icon.
  317. shInfo.hIcon = (HICON)LoadImage(hInstRes, MAKEINTRESOURCE(IDI_PACKAGE_WARNING),
  318. IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
  319. }
  320. }
  321. lpic->hDlgIcon = shInfo.hIcon;
  322. }
  323. else
  324. {
  325. // OK, we didn't have an extension,so use the packager icon
  326. if (!lpic->szIconPath || *lpic->szIconPath == TEXT('\0'))
  327. {
  328. lpic->hDlgIcon = (HICON)LoadImage(hInstRes, MAKEINTRESOURCE(IDI_PACKAGER),
  329. IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
  330. }
  331. }
  332. if (_pIDataAdviseHolder)
  333. _pIDataAdviseHolder->SendOnDataChange(this,0, NULL);
  334. if (_pViewSink)
  335. _pViewSink->OnViewChange(_dwViewAspects,_dwViewAdvf);
  336. #ifdef USE_RESOURCE_DLL
  337. FreeLibrary(hInstRes);
  338. #endif
  339. }
  340. void GetDisplayName(LPTSTR szName, LPCTSTR szPath)
  341. {
  342. LPTSTR pszTemp = PathFindFileName(szPath);
  343. StringCchCopy(szName, MAX_PATH, pszTemp); // all packager callers verified as MAX_PATH
  344. }
  345. /////////////////////////////////////////////////////////////////////////
  346. //
  347. // Stream Helper Functions
  348. //
  349. /////////////////////////////////////////////////////////////////////////
  350. HRESULT CopyFileToStream(LPTSTR lpFileName, IStream* pstm, DWORD * pdwFileLength)
  351. {
  352. //
  353. // copies the given file to the current seek pointer in the given stream
  354. // return: S_OK -- successfully copied
  355. // E_POINTER -- one of the pointers was NULL
  356. // E_OUTOFMEMORY -- out of memory
  357. // E_FAIL -- other error
  358. //
  359. LPVOID lpMem;
  360. HANDLE hFile = INVALID_HANDLE_VALUE;
  361. HRESULT hr;
  362. DWORD dwSizeLow;
  363. DWORD dwSizeHigh;
  364. DWORD dwPosLow = 0L;
  365. LONG lPosHigh = 0L;
  366. DebugMsg(DM_TRACE,"pack - CopyFileToStream called.");
  367. ASSERT(pdwFileLength);
  368. if(pdwFileLength)
  369. {
  370. *pdwFileLength = 0;
  371. }
  372. if (!pstm || !lpFileName)
  373. {
  374. DebugMsg(DM_TRACE," bad pointer!!");
  375. return E_POINTER;
  376. }
  377. // Allocate memory buffer for tranfer operation...
  378. if (!(lpMem = (LPVOID)GlobalAlloc(GPTR, BUFFERSIZE)))
  379. {
  380. DebugMsg(DM_TRACE, " couldn't alloc memory buffer!!");
  381. hr = E_OUTOFMEMORY;
  382. goto ErrRet;
  383. }
  384. // open file to copy to stream
  385. hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READWRITE, NULL,
  386. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  387. if (hFile == INVALID_HANDLE_VALUE)
  388. {
  389. DebugMsg(DM_TRACE, " couldn't open file!!");
  390. hr = HRESULT_FROM_WIN32(GetLastError());
  391. goto ErrRet;
  392. }
  393. // Figure out how much to copy...
  394. dwSizeLow = GetFileSize(hFile, &dwSizeHigh);
  395. ASSERT(dwSizeHigh == 0);
  396. SetFilePointer(hFile, 0L, NULL, FILE_BEGIN);
  397. // read in the file, and write to stream
  398. DWORD cbRead = BUFFERSIZE;
  399. DWORD cbWritten = BUFFERSIZE;
  400. while (cbRead == BUFFERSIZE && cbWritten == BUFFERSIZE)
  401. {
  402. if(ReadFile(hFile, lpMem, BUFFERSIZE, &cbRead, NULL))
  403. {
  404. if(!SUCCEEDED(pstm->Write(lpMem, cbRead, &cbWritten)))
  405. {
  406. hr = E_FAIL;
  407. goto ErrRet;
  408. }
  409. *pdwFileLength += cbWritten;
  410. }
  411. }
  412. // verify that we are now at end of block to copy
  413. dwPosLow = SetFilePointer(hFile, 0L, &lPosHigh, FILE_CURRENT);
  414. ASSERT(lPosHigh == 0);
  415. if (dwPosLow != dwSizeLow)
  416. {
  417. DebugMsg(DM_TRACE, " error copying file!!");
  418. hr = E_FAIL;
  419. goto ErrRet;
  420. }
  421. hr = S_OK;
  422. ErrRet:
  423. if (hFile != INVALID_HANDLE_VALUE)
  424. CloseHandle(hFile);
  425. if (lpMem)
  426. GlobalFree((HANDLE)lpMem);
  427. return hr;
  428. }
  429. HRESULT CopyStreamToFile(IStream* pstm, LPTSTR lpFileName, DWORD dwFileLength)
  430. {
  431. //
  432. // copies the contents of the given stream from the current seek pointer
  433. // to the end of the stream into the given file.
  434. //
  435. // NOTE: the given filename must not exist, if it does, the function fails
  436. // with E_FAIL
  437. //
  438. // return: S_OK -- successfully copied
  439. // E_POINTER -- one of the pointers was NULL
  440. // E_OUTOFMEMORY -- out of memory
  441. // E_FAIL -- other error
  442. //
  443. LPVOID lpMem;
  444. HANDLE hFile = INVALID_HANDLE_VALUE;
  445. HRESULT hr = S_OK;
  446. DebugMsg(DM_TRACE,"pack - CopyStreamToFile called.");
  447. // pstm must be a valid stream that is open for reading
  448. // lpFileName must be a valid filename to be written
  449. //
  450. if (!pstm || !lpFileName)
  451. return E_POINTER;
  452. // Allocate memory buffer...
  453. if (!(lpMem = (LPVOID)GlobalAlloc(GPTR, BUFFERSIZE)))
  454. {
  455. DebugMsg(DM_TRACE, " couldn't alloc memory buffer!!");
  456. hr = E_OUTOFMEMORY;
  457. goto ErrRet;
  458. }
  459. // open file to receive stream data
  460. hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL,
  461. CREATE_NEW, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  462. if (hFile == INVALID_HANDLE_VALUE)
  463. {
  464. DebugMsg(DM_TRACE, " couldn't open file!!");
  465. hr = E_FAIL;
  466. goto ErrRet;
  467. }
  468. // read in the stream, and write to the file
  469. DWORD cbCopied = 0;
  470. DWORD cbRead = BUFFERSIZE;
  471. DWORD cbWritten = BUFFERSIZE;
  472. while (cbRead == BUFFERSIZE && cbWritten == BUFFERSIZE)
  473. {
  474. DWORD cbToCopy;
  475. hr = pstm->Read(lpMem, BUFFERSIZE, &cbRead);
  476. cbToCopy = cbRead;
  477. if(cbCopied + cbToCopy > dwFileLength)
  478. cbToCopy = dwFileLength - cbCopied;
  479. if(WriteFile(hFile, lpMem, cbToCopy, &cbWritten, NULL))
  480. {
  481. cbCopied += cbWritten;
  482. }
  483. }
  484. if (hr != S_OK)
  485. {
  486. DebugMsg(DM_TRACE, " error copying file!!");
  487. hr = E_FAIL;
  488. goto ErrRet;
  489. }
  490. ErrRet:
  491. if (hFile != INVALID_HANDLE_VALUE)
  492. CloseHandle(hFile);
  493. if (lpMem)
  494. GlobalFree((HANDLE)lpMem);
  495. return hr;
  496. }
  497. // FEATURE: write persistence formats in UNICODE!
  498. HRESULT StringReadFromStream(IStream* pstm, LPSTR pszBuf, UINT cchBuf)
  499. {
  500. //
  501. // read byte by byte until we hit the null terminating char
  502. // return: the number of bytes read
  503. //
  504. UINT cch = 0;
  505. do
  506. {
  507. pstm->Read(pszBuf, sizeof(CHAR), NULL);
  508. cch++;
  509. } while (*pszBuf++ && cch <= cchBuf);
  510. return cch;
  511. }
  512. DWORD _CBString(LPCSTR psz)
  513. {
  514. return sizeof(psz[0]) * (lstrlenA(psz) + 1);
  515. }
  516. HRESULT StringWriteToStream(IStream* pstm, LPCSTR psz, DWORD *pdwWrite)
  517. {
  518. DWORD dwWrite;
  519. DWORD dwSize = _CBString(psz);
  520. HRESULT hr = pstm->Write(psz, dwSize, &dwWrite);
  521. if (SUCCEEDED(hr))
  522. *pdwWrite += dwWrite;
  523. return hr;
  524. }
  525. // parse pszPath into a unquoted path string and put the args in pszArgs
  526. //
  527. // returns:
  528. // TRUE we verified the thing exists
  529. // FALSE it may not exist
  530. //
  531. // taken from \ccshell\shell32\link.c
  532. //
  533. BOOL PathSeparateArgs(LPTSTR pszPath, LPTSTR pszArgs, DWORD cch)
  534. {
  535. LPTSTR pszT;
  536. PathRemoveBlanks(pszPath);
  537. // if the unquoted sting exists as a file just use it
  538. if (PathFileExists(pszPath))
  539. {
  540. *pszArgs = 0;
  541. return TRUE;
  542. }
  543. pszT = PathGetArgs(pszPath);
  544. if (*pszT)
  545. *(pszT - 1) = TEXT('\0');
  546. StringCchCopy(pszArgs, cch, pszT);
  547. PathUnquoteSpaces(pszPath);
  548. return FALSE;
  549. }
  550. int CPackage::_GiveWarningMsg()
  551. {
  552. int iResult = IDOK;
  553. LPWSTR szFileName = NULL;
  554. if(_pEmbed && *_pEmbed->fd.cFileName)
  555. {
  556. szFileName = _pEmbed->fd.cFileName;
  557. }
  558. else if(_lpic)
  559. {
  560. szFileName = _lpic->szIconPath;
  561. }
  562. LPTSTR szExt = NULL;
  563. if(szFileName)
  564. szExt = PathFindExtension(szFileName);
  565. UINT uWarningMsg = 0;
  566. if(szExt)
  567. {
  568. if(IsProgIDInList(NULL, szExt, c_arszExecutableExtns, ARRAYSIZE(c_arszExecutableExtns)))
  569. {
  570. uWarningMsg = IDS_PACKAGE_EXECUTABLE_WARNING;
  571. }
  572. else if(IsProgIDInList(NULL, szExt, c_arszUnsafeExts, ARRAYSIZE(c_arszUnsafeExts)))
  573. {
  574. uWarningMsg = IDS_PACKAGE_WARNING;
  575. }
  576. }
  577. if(uWarningMsg)
  578. {
  579. WCHAR szText[512];
  580. WCHAR szTitle[80];
  581. int iTryAgain = 0;
  582. #ifdef USE_RESOURCE_DLL
  583. HINSTANCE hInstRes = LoadLibraryEx(L"sp1res.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
  584. if(!hInstRes)
  585. return E_FAIL;
  586. #endif
  587. LoadString(hInstRes, uWarningMsg, szText, ARRAYSIZE(szText));
  588. LoadString(hInstRes, IDS_WARNING_DLG_TITLE, szTitle, ARRAYSIZE(szTitle));
  589. iResult = MessageBox(NULL, szText, szTitle, MB_OKCANCEL | MB_ICONWARNING | MB_DEFBUTTON2 | MB_SETFOREGROUND);
  590. #ifdef USE_RESOURCE_DLL
  591. FreeLibrary(hInstRes);
  592. #endif
  593. }
  594. return iResult;
  595. }