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.

943 lines
18 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
  4. //
  5. //
  6. // This workspace contains two projects -
  7. // 1. ProgHelp which implements the Progress Interface
  8. // 2. The Sample application WmdmApp.
  9. //
  10. // ProgHelp.dll needs to be registered first for the SampleApp to run.
  11. // Includes
  12. //
  13. #include "appPCH.h"
  14. // Reg function variables
  15. //
  16. static HINSTANCE _hInst = NULL;
  17. static HKEY _hkeyRoot = NULL;
  18. DWORD GetTheFileSize( LPSTR pszFile )
  19. {
  20. DWORD dwSize = 0xFFFFFFFF;
  21. HANDLE hFile;
  22. hFile = CreateFile(
  23. pszFile,
  24. GENERIC_READ,
  25. FILE_SHARE_READ,
  26. NULL,
  27. OPEN_EXISTING,
  28. FILE_FLAG_SEQUENTIAL_SCAN,
  29. NULL
  30. );
  31. if( INVALID_HANDLE_VALUE != hFile )
  32. {
  33. dwSize = GetFileSize( hFile, NULL );
  34. CloseHandle( hFile );
  35. }
  36. return dwSize;
  37. }
  38. //
  39. //
  40. // Registry functions
  41. //
  42. //
  43. VOID SetRegistryParams( HINSTANCE hInst, HKEY hkeyRoot )
  44. {
  45. _hInst = hInst;
  46. _hkeyRoot = hkeyRoot;
  47. }
  48. DWORD GetRegDword_StrTbl(
  49. UINT uPathID,
  50. UINT uKeyID,
  51. DWORD dwDefault,
  52. BOOL bStore
  53. )
  54. {
  55. CHAR szPath[MAX_PATH];
  56. CHAR szKey[MAX_PATH];
  57. LoadString( _hInst, uPathID, szPath, sizeof(szPath) );
  58. LoadString( _hInst, uKeyID, szKey, sizeof(szKey) );
  59. return GetRegDword(
  60. szPath,
  61. szKey,
  62. dwDefault,
  63. bStore
  64. );
  65. }
  66. DWORD GetRegDword(
  67. LPSTR szPath,
  68. LPSTR szKey,
  69. DWORD dwDefault,
  70. BOOL bStore
  71. )
  72. {
  73. DWORD dwRetCode;
  74. HKEY hkey;
  75. DWORD dwDisp;
  76. DWORD dwData;
  77. DWORD dwLen = sizeof(DWORD);
  78. dwRetCode = RegCreateKeyEx(
  79. _hkeyRoot,
  80. szPath,
  81. 0,
  82. NULL,
  83. REG_OPTION_NON_VOLATILE,
  84. KEY_ALL_ACCESS,
  85. NULL,
  86. &hkey,
  87. &dwDisp
  88. );
  89. if( dwRetCode != ERROR_SUCCESS )
  90. return dwDefault;
  91. dwRetCode = RegQueryValueEx(
  92. hkey,
  93. szKey,
  94. NULL,
  95. NULL,
  96. (LPBYTE)&dwData,
  97. &dwLen
  98. );
  99. if( dwRetCode != ERROR_SUCCESS )
  100. {
  101. if( bStore && hkey != NULL )
  102. {
  103. // Store default in the registry
  104. RegSetValueEx(
  105. hkey,
  106. szKey,
  107. 0L,
  108. REG_DWORD,
  109. (CONST BYTE *)&dwDefault,
  110. dwLen
  111. );
  112. }
  113. dwData = dwDefault;
  114. }
  115. RegCloseKey( hkey );
  116. return dwData;
  117. }
  118. LPSTR GetRegStr_StrTblDefault(
  119. UINT uPathID,
  120. UINT uKeyID,
  121. UINT uDefaultID,
  122. BOOL bStore
  123. )
  124. {
  125. CHAR szPath[MAX_PATH];
  126. CHAR szKey[MAX_PATH];
  127. CHAR szDefault[MAX_PATH];
  128. LoadString( _hInst, uPathID, szPath, sizeof(szPath) );
  129. LoadString( _hInst, uKeyID, szKey, sizeof(szKey) );
  130. LoadString( _hInst, uDefaultID, szDefault, sizeof(szDefault) );
  131. return GetRegStr(
  132. szPath,
  133. szKey,
  134. szDefault,
  135. bStore
  136. );
  137. }
  138. LPSTR GetRegStr_StrTbl(
  139. UINT uPathID,
  140. UINT uKeyID,
  141. LPSTR szDefault,
  142. BOOL bStore
  143. )
  144. {
  145. CHAR szPath[MAX_PATH];
  146. CHAR szKey[MAX_PATH];
  147. LoadString( _hInst, uPathID, szPath, sizeof(szPath) );
  148. LoadString( _hInst, uKeyID, szKey, sizeof(szKey) );
  149. return GetRegStr(
  150. szPath,
  151. szKey,
  152. szDefault,
  153. bStore
  154. );
  155. }
  156. LPSTR GetRegStr(
  157. LPSTR szPath,
  158. LPSTR szKey,
  159. LPSTR szDefault,
  160. BOOL bStore
  161. )
  162. {
  163. HKEY hkey;
  164. BOOL bFound = FALSE;
  165. DWORD dwRetCode;
  166. DWORD dwDisp;
  167. CHAR szTmp[MAX_PATH];
  168. DWORD dwSzLen = sizeof(szTmp);
  169. LPVOID lpvValue;
  170. dwRetCode = RegCreateKeyEx(
  171. _hkeyRoot,
  172. szPath,
  173. 0,
  174. NULL,
  175. REG_OPTION_NON_VOLATILE,
  176. KEY_ALL_ACCESS,
  177. NULL,
  178. &hkey,
  179. &dwDisp
  180. );
  181. if( dwRetCode == ERROR_SUCCESS )
  182. {
  183. // We've opened the key, now find the value for szKey
  184. dwRetCode = RegQueryValueEx(
  185. hkey,
  186. szKey,
  187. NULL,
  188. NULL,
  189. (LPBYTE)szTmp,
  190. &dwSzLen
  191. );
  192. bFound = ( dwRetCode == ERROR_SUCCESS );
  193. }
  194. if( !bFound )
  195. {
  196. if( szDefault == NULL )
  197. return NULL;
  198. // use default
  199. dwSzLen = lstrlen(szDefault);
  200. if( bStore && hkey != NULL )
  201. {
  202. // Store default in the registry
  203. RegSetValueEx(
  204. hkey,
  205. szKey,
  206. 0L,
  207. REG_SZ,
  208. (CONST BYTE *)szDefault,
  209. dwSzLen
  210. );
  211. }
  212. }
  213. lpvValue = (LPVOID) MemAlloc( dwSzLen + 1 );
  214. if( lpvValue == NULL )
  215. {
  216. return NULL;
  217. }
  218. lstrcpyn((char *)lpvValue, bFound? szTmp : szDefault, dwSzLen+1); //allocated dwSzLen+1 bytes, where length of szDefault and szTemp <= dwSzLen
  219. if( hkey != NULL )
  220. {
  221. RegCloseKey( hkey );
  222. }
  223. return (LPSTR)lpvValue;
  224. }
  225. VOID WriteRegDword_StrTbl(
  226. UINT uPathID,
  227. UINT uKeyID,
  228. DWORD dwValue
  229. )
  230. {
  231. CHAR szPath[MAX_PATH];
  232. CHAR szKey[MAX_PATH];
  233. LoadString( _hInst, uPathID, szPath, sizeof(szPath) );
  234. LoadString( _hInst, uKeyID, szKey, sizeof(szKey) );
  235. WriteRegDword(
  236. szPath,
  237. szKey,
  238. dwValue
  239. );
  240. }
  241. VOID WriteRegDword(
  242. LPSTR szPath,
  243. LPSTR szKey,
  244. DWORD dwValue
  245. )
  246. {
  247. HKEY hkey;
  248. DWORD dwRetCode;
  249. DWORD dwDisp;
  250. dwRetCode = RegCreateKeyEx(
  251. _hkeyRoot,
  252. szPath,
  253. 0,
  254. NULL,
  255. REG_OPTION_NON_VOLATILE,
  256. KEY_ALL_ACCESS,
  257. NULL,
  258. &hkey,
  259. &dwDisp
  260. );
  261. if( dwRetCode == ERROR_SUCCESS )
  262. {
  263. RegSetValueEx(
  264. hkey,
  265. szKey,
  266. 0,
  267. REG_DWORD,
  268. (LPBYTE)&dwValue,
  269. sizeof(DWORD)
  270. );
  271. RegCloseKey( hkey );
  272. }
  273. }
  274. VOID WriteRegStr_StrTbl(
  275. UINT uPathID,
  276. UINT uKeyID,
  277. LPSTR szValue
  278. )
  279. {
  280. CHAR szPath[MAX_PATH];
  281. CHAR szKey[MAX_PATH];
  282. LoadString( _hInst, uPathID, szPath, sizeof(szPath) );
  283. LoadString( _hInst, uKeyID, szKey, sizeof(szKey) );
  284. WriteRegStr(
  285. szPath,
  286. szKey,
  287. szValue
  288. );
  289. }
  290. VOID WriteRegStr(
  291. LPSTR szPath,
  292. LPSTR szKey,
  293. LPSTR szValue
  294. )
  295. {
  296. HKEY hkey;
  297. DWORD dwRetCode;
  298. DWORD dwDisp;
  299. dwRetCode = RegCreateKeyEx(
  300. _hkeyRoot,
  301. szPath,
  302. 0,
  303. NULL,
  304. REG_OPTION_NON_VOLATILE,
  305. KEY_ALL_ACCESS,
  306. NULL,
  307. &hkey,
  308. &dwDisp
  309. );
  310. if( dwRetCode == ERROR_SUCCESS )
  311. {
  312. RegSetValueEx(
  313. hkey,
  314. szKey,
  315. 0,
  316. REG_SZ,
  317. (LPBYTE)szValue,
  318. lstrlen(szValue)+1
  319. );
  320. RegCloseKey( hkey );
  321. }
  322. }
  323. VOID StripPath( LPSTR szFullPath )
  324. {
  325. LPSTR lpc = GetFileName( szFullPath );
  326. if( !lpc || lpc == szFullPath )
  327. return;
  328. lstrcpy( szFullPath, lpc ); //dest is a substring of source, hence OK
  329. }
  330. LPSTR GetFileName( LPSTR lpszFullPath )
  331. {
  332. LPSTR lpszFileName;
  333. if( !lpszFullPath )
  334. {
  335. return NULL;
  336. }
  337. for( lpszFileName = lpszFullPath; *lpszFullPath; lpszFullPath = AnsiNext(lpszFullPath) )
  338. {
  339. if( *lpszFullPath == '\\' )
  340. {
  341. lpszFileName = lpszFullPath + 1;
  342. }
  343. }
  344. return lpszFileName;
  345. }
  346. WPARAM DoMsgLoop( BOOL fForever )
  347. {
  348. MSG msg;
  349. while( TRUE )
  350. {
  351. if( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
  352. {
  353. if( !GetMessage(&msg, NULL, 0, 0) )
  354. {
  355. break;
  356. }
  357. // Make sure all keyboard input gets posted to the main app window
  358. // in case it wants to handle it.
  359. //
  360. if( msg.message == WM_CHAR && msg.hwnd != g_hwndMain )
  361. PostMessage( g_hwndMain, msg.message, msg.wParam, msg.lParam );
  362. if( msg.message == WM_KEYDOWN && msg.hwnd != g_hwndMain )
  363. PostMessage( g_hwndMain, msg.message, msg.wParam, msg.lParam );
  364. TranslateMessage( &msg );
  365. DispatchMessage( &msg );
  366. }
  367. else if( fForever )
  368. {
  369. WaitMessage();
  370. }
  371. else
  372. {
  373. return 0;
  374. }
  375. }
  376. return msg.wParam;
  377. }
  378. LPSTR DropListToBuffer( HDROP hDrop, LIST_TYPE listType, UINT *uNumObjs )
  379. {
  380. INT i;
  381. LPSTR lpszFiles = NULL;
  382. LPSTR lpsz = NULL;
  383. INT nLen = 0;
  384. INT nObjs = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 );
  385. // count the size needed for the files list
  386. for( i=0; i < nObjs; i++ )
  387. {
  388. // + 1 for the null terminator, + 2 for the pair of double quotes
  389. nLen += DragQueryFile( hDrop, i, NULL, 0 ) + 1;
  390. // need room for the pair of double quotes
  391. if( listType == LTB_SPACE_SEP )
  392. nLen += 2;
  393. }
  394. nLen++;
  395. // allocate the files list buffer
  396. lpszFiles = (LPSTR) MemAlloc( nLen );
  397. lpsz = lpszFiles;
  398. if( !lpszFiles )
  399. return NULL;
  400. // Populate the files list with the dropped file/folder names.
  401. for( i=0; i < nObjs; i++ )
  402. {
  403. if( listType == LTB_SPACE_SEP )
  404. *lpsz++ = '\"';
  405. nLen = DragQueryFile( hDrop, i, lpsz, MAX_PATH );
  406. lpsz += nLen;
  407. if( listType == LTB_SPACE_SEP )
  408. *lpsz++ = '\"';
  409. if( listType == LTB_SPACE_SEP && i != nObjs-1 )
  410. *lpsz++ = ' ';
  411. else if( listType == LTB_NULL_TERM )
  412. *lpsz++ = 0;
  413. }
  414. // append null terminator
  415. *lpsz = 0;
  416. if( uNumObjs )
  417. {
  418. *uNumObjs = (UINT) nObjs;
  419. }
  420. return lpszFiles;
  421. }
  422. BOOL CenterWindow( HWND hwnd, HWND hwndRef )
  423. {
  424. RECT rc;
  425. RECT rcRef;
  426. if( !hwnd )
  427. return FALSE;
  428. if( !GetClientRect(hwnd, &rc) )
  429. return FALSE;
  430. if( !GetWindowRect((hwndRef ? hwndRef : GetDesktopWindow()), &rcRef) )
  431. return FALSE;
  432. SetWindowPos(
  433. hwnd,
  434. NULL,
  435. rcRef.left + (rcRef.right - rcRef.left - rc.right)/2,
  436. rcRef.top + (rcRef.bottom - rcRef.top - rc.bottom)/2,
  437. 0, 0,
  438. SWP_NOSIZE | SWP_NOZORDER
  439. );
  440. return TRUE;
  441. }
  442. VOID BringWndToTop( HWND hwnd )
  443. {
  444. BringWindowToTop( hwnd );
  445. SetForegroundWindow( hwnd );
  446. SetWindowPos(
  447. hwnd,
  448. HWND_TOPMOST,
  449. 0, 0, 0, 0,
  450. SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW
  451. );
  452. UpdateWindow( hwnd );
  453. SetWindowPos(
  454. hwnd,
  455. HWND_NOTOPMOST,
  456. 0, 0, 0, 0,
  457. SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW
  458. );
  459. SetWindowPos(
  460. hwnd,
  461. HWND_TOP,
  462. 0, 0, 0, 0,
  463. SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW
  464. );
  465. UpdateWindow( hwnd );
  466. ShowWindow( hwnd, SW_SHOWNORMAL );
  467. }
  468. HANDLE WaitForMutex( LPSTR pszMutexName, DWORD dwRetryTime, DWORD dwTimeout )
  469. {
  470. HANDLE hMutex = NULL;
  471. DWORD dwStartTime = GetTickCount();
  472. // wait for the mutex to open up
  473. while( TRUE )
  474. {
  475. hMutex = CreateMutex( NULL, TRUE, pszMutexName );
  476. if( hMutex )
  477. {
  478. if( GetLastError() == ERROR_ALREADY_EXISTS )
  479. {
  480. // someone else has the mutex, so wait
  481. ReleaseMutex( hMutex );
  482. CloseHandle( hMutex );
  483. }
  484. else
  485. {
  486. // got mutex
  487. break;
  488. }
  489. // check for timeout if one was specified
  490. if( dwTimeout != (DWORD)-1 )
  491. {
  492. if( GetTickCount() > dwStartTime + dwTimeout )
  493. {
  494. hMutex = NULL;
  495. break;
  496. }
  497. }
  498. }
  499. // Wait for dwRetryTime clock ticks to try again
  500. //
  501. {
  502. DWORD dwStartWait = GetTickCount();
  503. DWORD dwEndWait = dwStartWait + dwRetryTime;
  504. while( GetTickCount() <= dwEndWait )
  505. {
  506. DoMsgLoop( FALSE );
  507. }
  508. }
  509. }
  510. return hMutex;
  511. }
  512. LPSTR FormatBytesToSz(
  513. DWORD dwLowBytes,
  514. DWORD dwHighBytes,
  515. DWORD dwMultiplier,
  516. LPSTR psz, size_t cbMax
  517. )
  518. {
  519. INT64 nBytes = ( (INT64)dwHighBytes << 32 | (INT64)dwLowBytes ) * dwMultiplier;
  520. _ASSERT (psz != NULL && cbMax > 0);
  521. // Insert a comma if the size is big enough
  522. //
  523. if( nBytes < 1024 )
  524. {
  525. char szFormat[MAX_PATH];
  526. LoadString( _hInst, IDS_BYTESSIZE_NOCOMMA, szFormat, sizeof(szFormat) );
  527. dwLowBytes = (DWORD)nBytes;
  528. StringCbPrintf(psz, cbMax, szFormat, dwLowBytes); //not checking return value of this function as the out string is for display only
  529. //and the fn will always null terminate the string
  530. return psz;
  531. }
  532. else if( nBytes < 1024*1024 )
  533. {
  534. dwLowBytes = (DWORD)(nBytes / 1024 );
  535. return FormatKBToKB_Sz( dwLowBytes, psz, cbMax );
  536. }
  537. else
  538. {
  539. dwLowBytes = (DWORD)(nBytes / 1024 );
  540. return FormatKBToMB_Sz( dwLowBytes, psz, cbMax );
  541. }
  542. }
  543. LPSTR FormatBytesToKB_Sz( DWORD dwBytes, LPSTR pszKB, size_t cbMax )
  544. {
  545. // Insert a comma if the size is big enough
  546. //
  547. _ASSERT (pszKB != NULL && cbMax > 0);
  548. if( dwBytes >= 1024 )
  549. {
  550. return FormatKBToKB_Sz( dwBytes/1024, pszKB, cbMax );
  551. }
  552. else
  553. {
  554. char szFormat[MAX_PATH];
  555. LoadString( _hInst, IDS_BYTESSIZE_NOCOMMA, szFormat, sizeof(szFormat) );
  556. StringCbPrintf(pszKB, cbMax, szFormat, dwBytes); //not checking return value of this function as the out string is for display only
  557. //and the fn will always null terminate the string
  558. return pszKB;
  559. }
  560. }
  561. LPSTR FormatKBToKB_Sz( DWORD dwKB, LPSTR pszKB, size_t cbMax )
  562. {
  563. char szFormat[MAX_PATH];
  564. // Insert a comma if the size is big enough
  565. //
  566. _ASSERT (pszKB != NULL && cbMax > 0);
  567. if( dwKB < 1000 )
  568. {
  569. LoadString( _hInst, IDS_KBSIZE_NOCOMMA, szFormat, sizeof(szFormat) );
  570. StringCbPrintf(pszKB, cbMax, szFormat, dwKB); //not checking return value of this function as the out string is for display only
  571. //and the fn will always null terminate the string
  572. }
  573. else
  574. {
  575. LoadString( _hInst, IDS_KBSIZE_COMMA, szFormat, sizeof(szFormat) );
  576. StringCbPrintf(pszKB, cbMax, szFormat, dwKB/1000, dwKB%1000); //not checking return value of this function as the out string is for display only
  577. //and the fn will always null terminate the string
  578. }
  579. return pszKB;
  580. }
  581. LPSTR FormatKBToMB_Sz( DWORD dwKB, LPSTR pszMB, size_t cbMax )
  582. {
  583. char szFormat[MAX_PATH];
  584. DWORD dwMB = dwKB / 1024;
  585. _ASSERT (pszKB != NULL && cbMax > 0);
  586. // Insert a comma if the size is big enough
  587. //
  588. if( dwMB < 100 )
  589. {
  590. LoadString( _hInst, IDS_MBSIZE_DECIMAL, szFormat, sizeof(szFormat) );
  591. StringCbPrintf(pszMB, cbMax, szFormat, dwKB/1024, dwKB%1024/100); //not checking return value of this function as the out string is for display only
  592. //and the fn will always null terminate the string
  593. }
  594. else if( dwMB < 1000 )
  595. {
  596. LoadString( _hInst, IDS_MBSIZE_NOCOMMA, szFormat, sizeof(szFormat) );
  597. StringCbPrintf(pszMB, cbMax, szFormat, dwMB); //not checking return value of this function as the out string is for display only
  598. //and the fn will always null terminate the string
  599. }
  600. else
  601. {
  602. LoadString( _hInst, IDS_MBSIZE_COMMA, szFormat, sizeof(szFormat) );
  603. StringCbPrintf(pszMB, cbMax, szFormat, dwMB/1000, dwMB%1000 ); //not checking return value of this function as the out string is for display only
  604. //and the fn will always null terminate the string
  605. }
  606. return pszMB;
  607. }
  608. LPSTR FormatSystemTimeToSz( SYSTEMTIME *pSysTime, LPSTR pszDateTime, DWORD cchMax )
  609. {
  610. INT nRet;
  611. SYSTEMTIME st;
  612. FILETIME ftUTC;
  613. FILETIME ftLocal;
  614. // Convert the UTC time to FILETIME
  615. //
  616. SystemTimeToFileTime( pSysTime, &ftUTC );
  617. // Convert the UTC FILETIME to a local FILETIME
  618. //
  619. FileTimeToLocalFileTime( &ftUTC, &ftLocal );
  620. // Convert the local FILETIME back to a SYSTEMTIME
  621. //
  622. FileTimeToSystemTime( &ftLocal, &st );
  623. // Get a user-displayable string for the SYSTEMTIME
  624. //
  625. nRet = GetDateFormat(
  626. LOCALE_USER_DEFAULT,
  627. 0,
  628. &st,
  629. NULL,
  630. pszDateTime,
  631. cchMax
  632. );
  633. if( nRet > 0 )
  634. {
  635. *(pszDateTime + nRet - 1) = ' ';
  636. nRet = GetTimeFormat(
  637. LOCALE_USER_DEFAULT,
  638. TIME_NOSECONDS,
  639. &st,
  640. NULL,
  641. pszDateTime + nRet,
  642. cchMax - nRet
  643. );
  644. }
  645. if( 0 == nRet )
  646. {
  647. *pszDateTime = 0;
  648. }
  649. return pszDateTime;
  650. }
  651. LPARAM ListView_GetLParam( HWND hwndListView, INT nItem )
  652. {
  653. LVITEM lvitem;
  654. lvitem.mask = LVIF_PARAM;
  655. lvitem.iSubItem = 0;
  656. lvitem.iItem = nItem;
  657. ListView_GetItem( hwndListView, &lvitem );
  658. return ( lvitem.lParam );
  659. }
  660. LPARAM TreeView_GetLParam( HWND hwndTreeView, HTREEITEM hItem )
  661. {
  662. TVITEM tvitem;
  663. tvitem.mask = TVIF_PARAM | TVIF_HANDLE;
  664. tvitem.hItem = hItem;
  665. TreeView_GetItem( hwndTreeView, &tvitem );
  666. return ( tvitem.lParam );
  667. }
  668. BOOL TreeView_SetLParam( HWND hwndTreeView, HTREEITEM hItem, LPARAM lParam )
  669. {
  670. TVITEM tvi;
  671. // Set up the item information
  672. //
  673. tvi.mask = TVIF_HANDLE | TVIF_PARAM;
  674. tvi.hItem = hItem;
  675. tvi.lParam = lParam;
  676. // Set the lParam
  677. //
  678. return TreeView_SetItem( hwndTreeView, &tvi );
  679. }
  680. VOID UiYield( void )
  681. {
  682. DoMsgLoop( FALSE );
  683. }
  684. INT GetShellIconIndex( LPCSTR pszItemName, LPTSTR szTypeBuffer, UINT cMaxChars )
  685. {
  686. int iIndex = -1;
  687. HANDLE hFile = INVALID_HANDLE_VALUE;
  688. SHFILEINFO si;
  689. CHAR szTempFile[MAX_PATH];
  690. static CHAR szTempPath[MAX_PATH];
  691. int iRetVal = 1;
  692. if( 0 == szTempPath[0] )
  693. {
  694. // Temporary paths used to get icon indices
  695. //
  696. iRetVal = GetTempPath( sizeof(szTempPath), szTempPath );
  697. }
  698. //if these functions fail, the return index will remain -1 and no icon will be displayed, which is not disasterous
  699. if (iRetVal && SUCCEEDED(StringCbPrintf (szTempFile, sizeof(szTempFile), "%s~%s", szTempPath, pszItemName)))
  700. {
  701. hFile = CreateFile(
  702. szTempFile,
  703. GENERIC_WRITE, 0, NULL,
  704. CREATE_ALWAYS,
  705. FILE_FLAG_DELETE_ON_CLOSE,
  706. NULL
  707. );
  708. SHGetFileInfo(
  709. szTempFile, 0,
  710. &si, sizeof(si),
  711. SHGFI_SYSICONINDEX | SHGFI_TYPENAME
  712. );
  713. if( szTypeBuffer )
  714. {
  715. StringCchCopy(szTypeBuffer, cMaxChars, si.szTypeName);
  716. }
  717. iIndex = si.iIcon;
  718. if( INVALID_HANDLE_VALUE != hFile )
  719. {
  720. CloseHandle( hFile );
  721. }
  722. }
  723. return( iIndex );
  724. }
  725. HICON GetShellIcon( LPCSTR pszItemName, BOOL bDirectory )
  726. {
  727. HICON hIcon = 0;
  728. HANDLE hFile = INVALID_HANDLE_VALUE;
  729. SHFILEINFO sfi;
  730. CHAR szTempFile[MAX_PATH];
  731. static CHAR szTempPath[MAX_PATH];
  732. DWORD_PTR bOk;
  733. int iRetVal = 1;
  734. if( 0 == szTempPath[0] )
  735. {
  736. // Temporary paths used to get icons
  737. //
  738. iRetVal = GetTempPath( sizeof(szTempPath), szTempPath );
  739. }
  740. if (iRetVal)
  741. {
  742. if( bDirectory )
  743. {
  744. // Get the icon for the temp directory
  745. strcpy( szTempFile, szTempPath ); //copying into same length string, hence OK
  746. }
  747. else
  748. {
  749. // Create a new file with this name and get it's icon.
  750. StringCbPrintf(szTempFile, sizeof(szTempFile), "%s~%s", szTempPath, pszItemName);
  751. hFile = CreateFile( szTempFile,
  752. GENERIC_WRITE, 0, NULL,
  753. CREATE_ALWAYS,
  754. FILE_FLAG_DELETE_ON_CLOSE,
  755. NULL );
  756. }
  757. bOk = SHGetFileInfo(szTempFile,
  758. 0,
  759. &sfi,
  760. sizeof(SHFILEINFO),
  761. SHGFI_ICON | SHGFI_SMALLICON);
  762. if( INVALID_HANDLE_VALUE != hFile )
  763. {
  764. CloseHandle( hFile );
  765. }
  766. }
  767. return ((bOk) ? sfi.hIcon : 0);
  768. }