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.

931 lines
25 KiB

  1. /****************************************************************************
  2. * *
  3. * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
  4. * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
  5. * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
  6. * PURPOSE. *
  7. * *
  8. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. *
  9. * *
  10. ****************************************************************************/
  11. //***************************************************************************
  12. //
  13. // Name: MDSPutil.cpp
  14. //
  15. // Description: Utility functions for MDSP
  16. //
  17. //***************************************************************************
  18. #include "stdafx.h"
  19. #include "MsPMSP.h"
  20. #include "MdspDefs.h"
  21. #include "wmsstd.h"
  22. #include "stdio.h"
  23. #include "DBT.h"
  24. #define STRSAFE_NO_DEPRECATE
  25. #include "strsafe.h"
  26. BOOL UtilSetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
  27. {
  28. if( g_bIsWinNT )
  29. {
  30. return SetFileAttributesW(lpFileName, dwFileAttributes);
  31. } else {
  32. BOOL bRet;
  33. char *szTmp=NULL;
  34. UINT uLen = 2*(wcslen(lpFileName)+1);
  35. szTmp = new char [uLen];
  36. if(!szTmp)
  37. {
  38. SetLastError(ERROR_OUTOFMEMORY);
  39. return FALSE;
  40. }
  41. WideCharToMultiByte(CP_ACP, NULL, lpFileName, -1, szTmp, uLen, NULL, NULL);
  42. bRet = SetFileAttributesA(szTmp, dwFileAttributes);
  43. if( szTmp )
  44. {
  45. delete [] szTmp;
  46. }
  47. return bRet;
  48. }
  49. }
  50. DWORD UtilGetFileAttributesW(LPCWSTR lpFileName)
  51. {
  52. if( g_bIsWinNT )
  53. {
  54. return GetFileAttributesW(lpFileName);
  55. } else {
  56. DWORD dwRet;
  57. char *szTmp=NULL;
  58. UINT uLen = 2*(wcslen(lpFileName)+1);
  59. szTmp = new char [uLen];
  60. if(!szTmp)
  61. {
  62. SetLastError(ERROR_OUTOFMEMORY);
  63. return 0xFFFFFFFF;
  64. }
  65. WideCharToMultiByte(CP_ACP, NULL, lpFileName, -1, szTmp, uLen, NULL, NULL);
  66. dwRet = GetFileAttributesA(szTmp);
  67. if( szTmp )
  68. {
  69. delete [] szTmp;
  70. }
  71. return dwRet;
  72. }
  73. }
  74. BOOL UtilCreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  75. {
  76. if( g_bIsWinNT )
  77. {
  78. return CreateDirectoryW(lpPathName, lpSecurityAttributes);
  79. } else {
  80. BOOL bRet;
  81. char *szTmp=NULL;
  82. UINT uLen = 2*(wcslen(lpPathName)+1);
  83. szTmp = new char [uLen];
  84. if(!szTmp)
  85. {
  86. SetLastError(ERROR_OUTOFMEMORY);
  87. return FALSE;
  88. }
  89. WideCharToMultiByte(CP_ACP, NULL, lpPathName, -1, szTmp, uLen, NULL, NULL);
  90. bRet = CreateDirectoryA(szTmp, lpSecurityAttributes);
  91. if( szTmp )
  92. {
  93. delete [] szTmp;
  94. }
  95. return bRet;
  96. }
  97. }
  98. HANDLE UtilCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
  99. {
  100. if( g_bIsWinNT )
  101. {
  102. return CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  103. } else {
  104. HANDLE hRet=INVALID_HANDLE_VALUE;
  105. char *szTmp=NULL;
  106. UINT uLen = 2*(wcslen(lpFileName)+1);
  107. szTmp = new char [uLen];
  108. if(!szTmp)
  109. {
  110. SetLastError(ERROR_OUTOFMEMORY);
  111. return INVALID_HANDLE_VALUE;
  112. }
  113. WideCharToMultiByte(CP_ACP, NULL, lpFileName, -1, szTmp, uLen, NULL, NULL);
  114. hRet = CreateFileA(szTmp, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  115. if( szTmp )
  116. {
  117. delete [] szTmp;
  118. }
  119. return hRet;
  120. }
  121. }
  122. BOOL UtilMoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
  123. {
  124. if( g_bIsWinNT )
  125. {
  126. return MoveFileW(lpExistingFileName, lpNewFileName);
  127. } else {
  128. BOOL bRet;
  129. char *szTmpSrc=NULL, *szTmpDst=NULL;
  130. szTmpSrc = new char [2*(wcslen(lpExistingFileName)+1)];
  131. szTmpDst = new char [2*(wcslen(lpNewFileName)+1)];
  132. if( (!szTmpSrc) || (!szTmpDst))
  133. {
  134. SetLastError(ERROR_OUTOFMEMORY);
  135. return FALSE;
  136. }
  137. WideCharToMultiByte(CP_ACP, NULL, lpExistingFileName, -1, szTmpSrc, 2*(wcslen(lpExistingFileName)+1), NULL, NULL);
  138. WideCharToMultiByte(CP_ACP, NULL, lpNewFileName, -1, szTmpDst, 2*(wcslen(lpNewFileName)+1), NULL, NULL);
  139. bRet = MoveFileA(szTmpSrc, szTmpDst);
  140. if( szTmpSrc )
  141. {
  142. delete [] szTmpSrc;
  143. szTmpSrc=NULL;
  144. }
  145. if( szTmpDst )
  146. {
  147. delete [] szTmpDst;
  148. szTmpDst=NULL;
  149. }
  150. return bRet;
  151. }
  152. }
  153. void MDSPNotifyDeviceConnection(WCHAR *wcsDeviceName, BOOL nIsConnect)
  154. {
  155. g_CriticalSection.Lock();
  156. for(int i=0; i<MDSP_MAX_DEVICE_OBJ; i++)
  157. {
  158. if( ( g_NotifyInfo[i].bValid ) &&
  159. ( !wcsncmp(wcsDeviceName, g_NotifyInfo[i].wcsDevName, 2) ) &&
  160. ( g_NotifyInfo[i].pIWMDMConnect ) )
  161. {
  162. //if ( nIsConnect )
  163. //((IWMDMConnect *)(g_NotifyInfo[i].pIWMDMConnect))->Connect();
  164. //else
  165. //((IWMDMConnect *)(g_NotifyInfo[i].pIWMDMConnect))->Disconnect();
  166. }
  167. }
  168. g_CriticalSection.Unlock();
  169. }
  170. void MDSPProcessDeviceChange(WPARAM wParam, LPARAM lParam)
  171. {
  172. PDEV_BROADCAST_HDR pdbch;
  173. PDEV_BROADCAST_VOLUME pdbcv;
  174. WCHAR cDrive[4];
  175. int wmId, wmMask;
  176. pdbch = (PDEV_BROADCAST_HDR) lParam;
  177. switch (pdbch->dbch_devicetype)
  178. {
  179. case DBT_DEVTYP_VOLUME:
  180. pdbcv = (PDEV_BROADCAST_VOLUME) pdbch;
  181. wcscpy(cDrive, L"C:");
  182. for(wmId=g_dwStartDrive; wmId<MDSP_MAX_DRIVE_COUNT; wmId++)
  183. {
  184. wmMask = 0x1 << wmId;
  185. if ( (pdbcv->dbcv_unitmask) & wmMask )
  186. {
  187. cDrive[0] = L'A'+wmId;
  188. switch (wParam)
  189. {
  190. case DBT_DEVICEARRIVAL:
  191. MDSPNotifyDeviceConnection(cDrive, TRUE);
  192. break;
  193. case DBT_DEVICEREMOVECOMPLETE:
  194. MDSPNotifyDeviceConnection(cDrive, FALSE);
  195. break;
  196. default:
  197. break;
  198. }
  199. }
  200. }
  201. break;
  202. default:
  203. break;
  204. }
  205. }
  206. /* ///////////////////////////////////////////////////////////////////////
  207. Routine Description:
  208. Registers for notification of changes in the device interfaces for
  209. the specified interface class GUID.
  210. Parameters:
  211. InterfaceClassGuid - The interface class GUID for the device
  212. interfaces.
  213. hDevNotify - Receives the device notification handle. On failure,
  214. this value is NULL.
  215. Return Value:
  216. If the function succeeds, the return value is TRUE.
  217. If the function fails, the return value is FALSE.
  218. //////////////////////////////////////////////////////////////////////// */
  219. DWORD DoRegisterDeviceInterface(HWND hWnd, GUID InterfaceClassGuid, HDEVNOTIFY *hDevNotify)
  220. {
  221. typedef HDEVNOTIFY (WINAPI *P_RDN)(HANDLE, LPVOID, DWORD);
  222. P_RDN pRegisterDeviceNotification;
  223. pRegisterDeviceNotification = (P_RDN)GetProcAddress(GetModuleHandle ("user32.dll"),
  224. "RegisterDeviceNotificationA");
  225. if( pRegisterDeviceNotification )
  226. {
  227. DEV_BROADCAST_VOLUME NotificationFilter;
  228. ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
  229. NotificationFilter.dbcv_size = sizeof(DEV_BROADCAST_VOLUME);
  230. NotificationFilter.dbcv_devicetype = DBT_DEVTYP_VOLUME;
  231. NotificationFilter.dbcv_unitmask = 0;
  232. NotificationFilter.dbcv_flags = DBTF_MEDIA;
  233. *hDevNotify = pRegisterDeviceNotification( hWnd,
  234. &NotificationFilter,
  235. DEVICE_NOTIFY_WINDOW_HANDLE
  236. );
  237. if(!*hDevNotify)
  238. {
  239. return GetLastError();
  240. }
  241. return ERROR_SUCCESS;
  242. } else
  243. return GetLastError();
  244. }
  245. BOOL DoUnregisterDeviceInterface(HDEVNOTIFY hDev)
  246. {
  247. typedef BOOL (WINAPI *P_URDN)(HDEVNOTIFY);
  248. P_URDN pUnregisterDeviceNotification;
  249. pUnregisterDeviceNotification = (P_URDN)GetProcAddress(GetModuleHandle ("user32.dll"),
  250. "UnregisterDeviceNotificationA");
  251. if( pUnregisterDeviceNotification )
  252. {
  253. return pUnregisterDeviceNotification(hDev);
  254. } else
  255. return FALSE;
  256. }
  257. HRESULT wcsParseDeviceName(WCHAR *wcsIn, WCHAR *wcsOut, DWORD dwOutBufSizeInChars)
  258. {
  259. WCHAR wcsTmp[MAX_PATH], *pWcs;
  260. HRESULT hr;
  261. hr = StringCchCopyW(wcsTmp, ARRAYSIZE(wcsTmp), wcsIn);
  262. if (FAILED(hr))
  263. {
  264. return hr;
  265. }
  266. pWcs = wcschr(wcsTmp, 0x5c);
  267. if( pWcs ) *pWcs=0;
  268. if (wcslen(wcsTmp) < dwOutBufSizeInChars)
  269. {
  270. wcscpy(wcsOut, wcsTmp);
  271. }
  272. else
  273. {
  274. return STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  275. }
  276. return S_OK;
  277. }
  278. HRESULT GetFileSizeRecursiveA(char *szPath, DWORD *pdwSizeLow, DWORD *pdwSizeHigh)
  279. {
  280. HRESULT hr=S_OK;
  281. HANDLE hFile, hFindFile=INVALID_HANDLE_VALUE;
  282. DWORD dwSizeLow=0, dwSizeHigh=0;
  283. WIN32_FIND_DATAA fd;
  284. char szLP[MAX_PATH+BACKSLASH_SZ_STRING_LENGTH+1];
  285. CARg(szPath);
  286. CARg(pdwSizeLow);
  287. CARg(pdwSizeHigh);
  288. CARg(szPath[0]);
  289. // strcpy(szLP, szPath);
  290. hr = StringCchCopyA(szLP, ARRAYSIZE(szLP)-BACKSLASH_SZ_STRING_LENGTH-1, szPath);
  291. if (FAILED(hr))
  292. {
  293. goto Error;
  294. }
  295. DWORD dwAttrib = GetFileAttributesA(szPath);
  296. if (dwAttrib == INVALID_FILE_ATTRIBUTES)
  297. {
  298. hr = HRESULT_FROM_WIN32(GetLastError());
  299. goto Error;
  300. }
  301. if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib )
  302. {
  303. if( szLP[strlen(szLP)-1] != 0x5c ) strcat(szLP, g_szBackslash);
  304. strcat(szLP, "*");
  305. hFindFile = FindFirstFileA(szLP, &fd);
  306. if ( hFindFile != INVALID_HANDLE_VALUE )
  307. {
  308. if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
  309. {
  310. szLP[strlen(szLP)-1] = 0; // erase the '*'
  311. // strcat(szLP, fd.cFileName);
  312. CORg(StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName));
  313. CORg(GetFileSizeRecursiveA(szLP, pdwSizeLow, pdwSizeHigh));
  314. }
  315. while ( FindNextFileA(hFindFile, &fd) )
  316. {
  317. if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
  318. {
  319. strcpy(szLP, szPath);
  320. if( szLP[strlen(szLP)-1] != 0x5c ) strcat(szLP, g_szBackslash);
  321. // strcat(szLP, fd.cFileName);
  322. CORg(StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName));
  323. CORg(GetFileSizeRecursiveA(szLP, pdwSizeLow, pdwSizeHigh));
  324. }
  325. }
  326. hr = GetLastError();
  327. if( hr == ERROR_NO_MORE_FILES ) hr=S_OK;
  328. else hr = HRESULT_FROM_WIN32(hr);
  329. }
  330. } else {
  331. hFile=CreateFileA(szPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  332. OPEN_EXISTING, 0, NULL);
  333. CWRg(hFile != INVALID_HANDLE_VALUE);
  334. dwSizeLow = GetFileSize(hFile, &dwSizeHigh);
  335. // CloseHandle(hFile);
  336. // CWRg( 0xFFFFFFFF != dwSizeLow );
  337. if (dwSizeLow == INVALID_FILE_SIZE)
  338. {
  339. DWORD dwLastError = GetLastError();
  340. if (dwLastError != NO_ERROR)
  341. {
  342. hr = HRESULT_FROM_WIN32(dwLastError);
  343. CloseHandle(hFile);
  344. goto Error;
  345. }
  346. }
  347. CloseHandle(hFile);
  348. // ha ha
  349. // *pdwSizeLow += dwSizeLow;
  350. // *pdwSizeHigh += dwSizeHigh;
  351. unsigned _int64 u64Size = ((unsigned _int64) dwSizeHigh << 32) | dwSizeLow;
  352. u64Size += *pdwSizeLow | ((unsigned _int64) (*pdwSizeHigh) << 32);
  353. *pdwSizeLow = (DWORD) (u64Size & 0xFFFFFFFF);
  354. *pdwSizeHigh = (DWORD) (u64Size >> 32);
  355. hr=S_OK;
  356. }
  357. Error:
  358. if(hFindFile != INVALID_HANDLE_VALUE )
  359. FindClose(hFindFile);
  360. return hr;
  361. }
  362. HRESULT GetFileSizeRecursiveW(WCHAR *wcsPath, DWORD *pdwSizeLow, DWORD *pdwSizeHigh)
  363. {
  364. HRESULT hr=S_OK;
  365. HANDLE hFile, hFindFile=INVALID_HANDLE_VALUE;
  366. DWORD dwSizeLow=0, dwSizeHigh=0;
  367. WIN32_FIND_DATAW wfd;
  368. WCHAR wcsLP[MAX_PATH+BACKSLASH_STRING_LENGTH+1];
  369. CARg(wcsPath);
  370. CARg(pdwSizeLow);
  371. CARg(pdwSizeHigh);
  372. CARg(wcsPath[0]);
  373. // wcscpy(wcsLP, wcsPath);
  374. hr = StringCchCopyW(wcsLP, ARRAYSIZE(wcsLP)-BACKSLASH_STRING_LENGTH-1, wcsPath);
  375. if (FAILED(hr))
  376. {
  377. goto Error;
  378. }
  379. DWORD dwAttrib = GetFileAttributesW(wcsPath);
  380. if (dwAttrib == INVALID_FILE_ATTRIBUTES)
  381. {
  382. hr = HRESULT_FROM_WIN32(GetLastError());
  383. goto Error;
  384. }
  385. if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib )
  386. {
  387. if( wcsLP[wcslen(wcsLP)-1] != 0x5c ) wcscat(wcsLP, g_wcsBackslash);
  388. wcscat(wcsLP, L"*");
  389. hFindFile = FindFirstFileW(wcsLP, &wfd);
  390. if ( hFindFile != INVALID_HANDLE_VALUE )
  391. {
  392. if( wcscmp(wfd.cFileName, L".") && wcscmp(wfd.cFileName, L"..") )
  393. {
  394. wcsLP[wcslen(wcsLP)-1] = 0; // erase the '*'
  395. // wcscat(wcsLP, wfd.cFileName);
  396. CORg(StringCchCatW(wcsLP, ARRAYSIZE(wcsLP), wfd.cFileName));
  397. CORg(GetFileSizeRecursiveW(wcsLP, pdwSizeLow, pdwSizeHigh));
  398. }
  399. while ( FindNextFileW(hFindFile, &wfd) )
  400. {
  401. if( wcscmp(wfd.cFileName, L".") && wcscmp(wfd.cFileName, L"..") )
  402. {
  403. wcscpy(wcsLP, wcsPath);
  404. if( wcsLP[wcslen(wcsLP)-1] != 0x5c ) wcscat(wcsLP, g_wcsBackslash);
  405. // wcscat(wcsLP, wfd.cFileName);
  406. CORg(StringCchCatW(wcsLP, ARRAYSIZE(wcsLP), wfd.cFileName));
  407. CORg(GetFileSizeRecursiveW(wcsLP, pdwSizeLow, pdwSizeHigh));
  408. }
  409. }
  410. hr = GetLastError();
  411. if( hr == ERROR_NO_MORE_FILES ) hr=S_OK;
  412. else hr = HRESULT_FROM_WIN32(hr);
  413. }
  414. } else {
  415. hFile=CreateFileW(wcsPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  416. OPEN_EXISTING, 0, NULL);
  417. CWRg(hFile != INVALID_HANDLE_VALUE);
  418. dwSizeLow = GetFileSize(hFile, &dwSizeHigh);
  419. // CloseHandle(hFile);
  420. // CWRg( 0xFFFFFFFF != dwSizeLow );
  421. if (dwSizeLow == INVALID_FILE_SIZE)
  422. {
  423. DWORD dwLastError = GetLastError();
  424. if (dwLastError != NO_ERROR)
  425. {
  426. hr = HRESULT_FROM_WIN32(dwLastError);
  427. CloseHandle(hFile);
  428. goto Error;
  429. }
  430. }
  431. CloseHandle(hFile);
  432. // ha ha
  433. // *pdwSizeLow += dwSizeLow;
  434. // *pdwSizeHigh += dwSizeHigh;
  435. unsigned _int64 u64Size = ((unsigned _int64) dwSizeHigh << 32) | dwSizeLow;
  436. u64Size += *pdwSizeLow | ((unsigned _int64) (*pdwSizeHigh) << 32);
  437. *pdwSizeLow = (DWORD) (u64Size & 0xFFFFFFFF);
  438. *pdwSizeHigh = (DWORD) (u64Size >> 32);
  439. hr=S_OK;
  440. }
  441. Error:
  442. if(hFindFile != INVALID_HANDLE_VALUE )
  443. FindClose(hFindFile);
  444. return hr;
  445. }
  446. HRESULT DeleteFileRecursiveW(WCHAR *wcsPath)
  447. {
  448. HRESULT hr=S_OK;
  449. CARg(wcsPath);
  450. CARg(wcsPath[0]);
  451. DWORD dwAttrib = GetFileAttributesW(wcsPath);
  452. if (dwAttrib == INVALID_FILE_ATTRIBUTES)
  453. {
  454. hr = HRESULT_FROM_WIN32(GetLastError());
  455. goto Error;
  456. }
  457. if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib )
  458. {
  459. HANDLE hFindFile=INVALID_HANDLE_VALUE;
  460. WIN32_FIND_DATAW wfd;
  461. WCHAR wcsLP[MAX_PATH+BACKSLASH_STRING_LENGTH+1];
  462. // wcscpy(wcsLP, wcsPath);
  463. hr = StringCchCopyW(wcsLP, ARRAYSIZE(wcsLP)-BACKSLASH_STRING_LENGTH-1, wcsPath);
  464. if (FAILED(hr))
  465. {
  466. goto Error;
  467. }
  468. if( wcsLP[wcslen(wcsLP)-1] != 0x5c ) wcscat(wcsLP, g_wcsBackslash);
  469. wcscat(wcsLP, L"*");
  470. hFindFile = FindFirstFileW(wcsLP, &wfd);
  471. if ( hFindFile != INVALID_HANDLE_VALUE )
  472. {
  473. do {
  474. if( wcscmp(wfd.cFileName, L".") && wcscmp(wfd.cFileName, L"..") )
  475. {
  476. wcscpy(wcsLP, wcsPath);
  477. if( wcsLP[wcslen(wcsLP)-1] != 0x5c ) wcscat(wcsLP, g_wcsBackslash);
  478. // wcscat(wcsLP, wfd.cFileName);
  479. hr = StringCchCatW(wcsLP, ARRAYSIZE(wcsLP), wfd.cFileName);
  480. if (FAILED(hr))
  481. {
  482. FindClose(hFindFile);
  483. CHRg(hr);
  484. }
  485. // CHRg(DeleteFileRecursiveW(wcsLP));
  486. hr = DeleteFileRecursiveW(wcsLP);
  487. if (FAILED(hr))
  488. {
  489. FindClose(hFindFile);
  490. CHRg(hr);
  491. }
  492. }
  493. } while ( FindNextFileW(hFindFile, &wfd) ) ;
  494. hr = GetLastError();
  495. FindClose(hFindFile);
  496. } else {
  497. hr = GetLastError();
  498. }
  499. // Until here this dir should be empty
  500. if( hr == ERROR_NO_MORE_FILES )
  501. {
  502. CWRg(RemoveDirectoryW(wcsPath));
  503. hr=S_OK;
  504. } else hr = HRESULT_FROM_WIN32(hr);
  505. } else {
  506. CWRg( DeleteFileW(wcsPath) );
  507. }
  508. Error:
  509. return hr;
  510. }
  511. HRESULT DeleteFileRecursiveA(char *szPath)
  512. {
  513. HRESULT hr=S_OK;
  514. CARg(szPath);
  515. CARg(szPath[0]);
  516. DWORD dwAttrib = GetFileAttributesA(szPath);
  517. if (dwAttrib == INVALID_FILE_ATTRIBUTES)
  518. {
  519. hr = HRESULT_FROM_WIN32(GetLastError());
  520. goto Error;
  521. }
  522. if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib )
  523. {
  524. HANDLE hFindFile=INVALID_HANDLE_VALUE;
  525. WIN32_FIND_DATAA fd;
  526. char szLP[MAX_PATH+BACKSLASH_SZ_STRING_LENGTH+1];
  527. hr = StringCchCopyA(szLP, ARRAYSIZE(szLP)-BACKSLASH_SZ_STRING_LENGTH-1, szPath);
  528. if (FAILED(hr))
  529. {
  530. goto Error;
  531. }
  532. if( szLP[strlen(szLP)-1] != 0x5c ) strcat(szLP, g_szBackslash);
  533. strcat(szLP, "*");
  534. hFindFile = FindFirstFileA(szLP, &fd);
  535. if ( hFindFile != INVALID_HANDLE_VALUE )
  536. {
  537. do {
  538. if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
  539. {
  540. strcpy(szLP, szPath);
  541. if( szLP[strlen(szLP)-1] != 0x5c ) strcat(szLP, g_szBackslash);
  542. // strcat(szLP, fd.cFileName);
  543. hr = StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName);
  544. if (FAILED(hr))
  545. {
  546. FindClose(hFindFile);
  547. CHRg(hr);
  548. }
  549. // CHRg(DeleteFileRecursive(szLP));
  550. hr = DeleteFileRecursiveA(szLP);
  551. if (FAILED(hr))
  552. {
  553. FindClose(hFindFile);
  554. CHRg(hr);
  555. }
  556. }
  557. } while ( FindNextFileA(hFindFile, &fd) ) ;
  558. hr = GetLastError();
  559. FindClose(hFindFile);
  560. } else {
  561. hr = GetLastError();
  562. }
  563. // Until here this dir should be empty
  564. if( hr == ERROR_NO_MORE_FILES )
  565. {
  566. CWRg(RemoveDirectory(szPath));
  567. hr=S_OK;
  568. } else hr = HRESULT_FROM_WIN32(hr);
  569. } else {
  570. CWRg( DeleteFileA(szPath) );
  571. }
  572. Error:
  573. return hr;
  574. }
  575. HRESULT SetGlobalDeviceStatus(WCHAR *wcsNameIn, DWORD dwStat, BOOL bClear)
  576. {
  577. HRESULT hr=S_OK;
  578. g_CriticalSection.Lock();
  579. CARg(wcsNameIn);
  580. WCHAR wcsName[ARRAYSIZE(g_GlobalDeviceInfo[0].wcsDevName)], *pWN;
  581. int i;
  582. pWN = &wcsName[0];
  583. HRESULT hrTemp = wcsParseDeviceName(wcsNameIn, pWN, ARRAYSIZE(wcsName));
  584. if (FAILED(hrTemp))
  585. {
  586. hr = hrTemp;
  587. goto Error;
  588. }
  589. // Search for existing entries to see if there is a match
  590. for(i=0; i<MDSP_MAX_DEVICE_OBJ; i++)
  591. {
  592. if( g_GlobalDeviceInfo[i].bValid )
  593. {
  594. if(!wcscmp(wcsName, g_GlobalDeviceInfo[i].wcsDevName) )
  595. {
  596. if( bClear )
  597. g_GlobalDeviceInfo[i].dwStatus = dwStat;
  598. else
  599. g_GlobalDeviceInfo[i].dwStatus |= dwStat;
  600. break; // a match has been found;
  601. }
  602. }
  603. }
  604. if( !(i<MDSP_MAX_DEVICE_OBJ) ) // new entry
  605. {
  606. for(i=0; i<MDSP_MAX_DEVICE_OBJ; i++)
  607. {
  608. if( !(g_GlobalDeviceInfo[i].bValid) ) // found empty space
  609. {
  610. wcscpy(g_GlobalDeviceInfo[i].wcsDevName, wcsName);
  611. g_GlobalDeviceInfo[i].bValid = TRUE;
  612. g_GlobalDeviceInfo[i].dwStatus = dwStat;
  613. break;
  614. }
  615. }
  616. }
  617. if( i<MDSP_MAX_DEVICE_OBJ )
  618. {
  619. hr = S_OK;
  620. } else {
  621. hr = hrNoMem;
  622. }
  623. Error:
  624. g_CriticalSection.Unlock();
  625. return hr;
  626. }
  627. HRESULT GetGlobalDeviceStatus(WCHAR *wcsNameIn, DWORD *pdwStat)
  628. {
  629. HRESULT hr;
  630. CARg(wcsNameIn);
  631. WCHAR wcsName[32], *pWN;
  632. int i;
  633. pWN = &wcsName[0];
  634. hr = wcsParseDeviceName(wcsNameIn, pWN, ARRAYSIZE(wcsName));
  635. if (FAILED(hr))
  636. {
  637. goto Error;
  638. }
  639. // Search for existing entries to see if there is a match
  640. for(i=0; i<MDSP_MAX_DEVICE_OBJ; i++)
  641. {
  642. if( g_GlobalDeviceInfo[i].bValid )
  643. {
  644. if(!wcscmp(wcsName, g_GlobalDeviceInfo[i].wcsDevName) )
  645. {
  646. *pdwStat = g_GlobalDeviceInfo[i].dwStatus;
  647. break; // a match has been found;
  648. }
  649. }
  650. }
  651. if( i<MDSP_MAX_DEVICE_OBJ )
  652. {
  653. hr = S_OK;
  654. } else {
  655. hr = E_FAIL;
  656. }
  657. Error:
  658. return hr;
  659. }
  660. HRESULT QuerySubFoldersAndFilesW(LPCWSTR wcsCurrentFolder, DWORD *pdwAttr)
  661. {
  662. HRESULT hr=E_FAIL;
  663. LPWSTR wcsName=NULL;
  664. int len;
  665. WIN32_FIND_DATAW wfd;
  666. int nErrorEnd=0;
  667. HANDLE hFFile=INVALID_HANDLE_VALUE;
  668. DWORD dwAttrib;
  669. CARg(wcsCurrentFolder);
  670. CARg(pdwAttr);
  671. len=wcslen(wcsCurrentFolder);
  672. CARg(len>2);
  673. wcsName = new WCHAR [len+BACKSLASH_STRING_LENGTH+MAX_PATH];
  674. CPRg(wcsName);
  675. wcscpy(wcsName, wcsCurrentFolder);
  676. if( wcsName[wcslen(wcsName)-1] != 0x5c ) wcscat(wcsName, g_wcsBackslash);
  677. wcscat(wcsName, L"*");
  678. while( !nErrorEnd )
  679. {
  680. if( hFFile == INVALID_HANDLE_VALUE ) {
  681. hFFile = FindFirstFileW(wcsName, &wfd);
  682. if( hFFile == INVALID_HANDLE_VALUE ) nErrorEnd = 1;
  683. } else {
  684. if( !FindNextFileW(hFFile, &wfd) ) nErrorEnd = 1;
  685. }
  686. if ( !nErrorEnd && hFFile != INVALID_HANDLE_VALUE )
  687. {
  688. if( !wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L"..") )
  689. continue;
  690. else {
  691. wcscpy(wcsName, wcsCurrentFolder);
  692. if( wcsName[wcslen(wcsName)-1] != 0x5c ) wcscat(wcsName, g_wcsBackslash);
  693. wcscat(wcsName, wfd.cFileName);
  694. dwAttrib = GetFileAttributesW(wcsName);
  695. if( dwAttrib & FILE_ATTRIBUTE_DIRECTORY )
  696. {
  697. *pdwAttr |= WMDM_STORAGE_ATTR_HAS_FOLDERS;
  698. // definition is in MDSPdefs.h #define ALSO_CHECK_FILES
  699. #ifndef ALSO_CHECK_FILES
  700. break;
  701. #endif
  702. }
  703. #ifdef ALSO_CHECK_FILES
  704. else {
  705. *pdwAttr |= WMDM_STORAGE_ATTR_HAS_FILES;
  706. }
  707. if( (*pdwAttr & WMDM_STORAGE_ATTR_HAS_FOLDERS) &&
  708. (*pdwAttr & WMDM_STORAGE_ATTR_HAS_FILES ) )
  709. {
  710. break; // No need to continue since we found both
  711. }
  712. #endif
  713. }
  714. } // End of If
  715. } // End of while
  716. hr=S_OK;
  717. Error:
  718. if( hFFile != INVALID_HANDLE_VALUE )
  719. FindClose(hFFile);
  720. if( wcsName )
  721. {
  722. delete [] wcsName;
  723. }
  724. return hr; // If FAILED(hr), sorry, can't do it.
  725. }
  726. HRESULT QuerySubFoldersAndFilesA(LPCSTR szCurrentFolder, DWORD *pdwAttr)
  727. {
  728. HRESULT hr=E_FAIL;
  729. LPSTR szName=NULL;
  730. int len;
  731. WIN32_FIND_DATAA fd;
  732. int nErrorEnd=0;
  733. HANDLE hFFile=INVALID_HANDLE_VALUE;
  734. DWORD dwAttrib;
  735. CARg(szCurrentFolder);
  736. CARg(pdwAttr);
  737. len=strlen(szCurrentFolder);
  738. CARg(len>2);
  739. szName = new char [len+BACKSLASH_SZ_STRING_LENGTH+MAX_PATH];
  740. CPRg(szName);
  741. strcpy(szName, szCurrentFolder);
  742. if( szName[strlen(szName)-1] != 0x5c ) strcat(szName, g_szBackslash);
  743. strcat(szName, "*");
  744. while( !nErrorEnd )
  745. {
  746. if( hFFile == INVALID_HANDLE_VALUE ) {
  747. hFFile = FindFirstFileA(szName, &fd);
  748. if( hFFile == INVALID_HANDLE_VALUE ) nErrorEnd = 1;
  749. } else {
  750. if( !FindNextFileA(hFFile, &fd) ) nErrorEnd = 1;
  751. }
  752. if ( !nErrorEnd && hFFile != INVALID_HANDLE_VALUE )
  753. {
  754. if( !strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..") )
  755. continue;
  756. else {
  757. strcpy(szName, szCurrentFolder);
  758. if( szName[strlen(szName)-1] != 0x5c ) strcat(szName, g_szBackslash);
  759. strcat(szName, fd.cFileName);
  760. dwAttrib = GetFileAttributesA(szName);
  761. if( dwAttrib & FILE_ATTRIBUTE_DIRECTORY )
  762. {
  763. *pdwAttr |= WMDM_STORAGE_ATTR_HAS_FOLDERS;
  764. // definition is in MDSPdefs.h #define ALSO_CHECK_FILES
  765. #ifndef ALSO_CHECK_FILES
  766. break;
  767. #endif
  768. }
  769. #ifdef ALSO_CHECK_FILES
  770. else {
  771. *pdwAttr |= WMDM_STORAGE_ATTR_HAS_FILES;
  772. }
  773. if( (*pdwAttr & WMDM_STORAGE_ATTR_HAS_FOLDERS) &&
  774. (*pdwAttr & WMDM_STORAGE_ATTR_HAS_FILES ) )
  775. {
  776. break; // No need to continue since we found both
  777. }
  778. #endif
  779. }
  780. } // End of If
  781. } // End of while
  782. hr=S_OK;
  783. Error:
  784. if( hFFile != INVALID_HANDLE_VALUE )
  785. FindClose(hFFile);
  786. if( szName )
  787. {
  788. delete [] szName;
  789. }
  790. return hr; // If FAILED(hr), sorry, can't do it.
  791. }
  792. HRESULT QuerySubFoldersAndFiles(LPCWSTR wcsCurrentFolder, DWORD *pdwAttr)
  793. {
  794. if( g_bIsWinNT )
  795. {
  796. return QuerySubFoldersAndFilesW(wcsCurrentFolder, pdwAttr);
  797. } else {
  798. HRESULT hr;
  799. char *szTmp=NULL;
  800. szTmp = new char [2*(wcslen(wcsCurrentFolder)+1)];
  801. if(!szTmp)
  802. {
  803. return HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  804. }
  805. WideCharToMultiByte(CP_ACP, NULL, wcsCurrentFolder, -1, szTmp, 2*(wcslen(wcsCurrentFolder)+1), NULL, NULL);
  806. hr = QuerySubFoldersAndFilesA(szTmp, pdwAttr);
  807. if( szTmp )
  808. {
  809. delete [] szTmp;
  810. }
  811. return hr;
  812. }
  813. }