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.

516 lines
12 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // � 1999 Microsoft Corporation. All rights reserved.
  4. //
  5. // Refer to your End User License Agreement for details on your rights/restrictions to use these sample files.
  6. //
  7. // MSHDSP.DLL is a sample WMDM Service Provider(SP) that enumerates fixed drives.
  8. // This sample shows you how to implement an SP according to the WMDM documentation.
  9. // This sample uses fixed drives on your PC to emulate portable media, and
  10. // shows the relationship between different interfaces and objects. Each hard disk
  11. // volume is enumerated as a device and directories and files are enumerated as
  12. // Storage objects under respective devices. You can copy non-SDMI compliant content
  13. // to any device that this SP enumerates. To copy an SDMI compliant content to a
  14. // device, the device must be able to report a hardware embedded serial number.
  15. // Hard disks do not have such serial numbers.
  16. //
  17. // To build this SP, you are recommended to use the MSHDSP.DSP file under Microsoft
  18. // Visual C++ 6.0 and run REGSVR32.EXE to register the resulting MSHDSP.DLL. You can
  19. // then build the sample application from the WMDMAPP directory to see how it gets
  20. // loaded by the application. However, you need to obtain a certificate from
  21. // Microsoft to actually run this SP. This certificate would be in the KEY.C file
  22. // under the INCLUDE directory for one level up.
  23. // MDSPEnumStorage.cpp : Implementation of CMDSPEnumStorage
  24. #include "hdspPCH.h"
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CMDSPEnumStorage
  27. CMDSPEnumStorage::CMDSPEnumStorage()
  28. {
  29. m_hFFile=INVALID_HANDLE_VALUE; // this is similar to a cursor
  30. m_nEndSearch=0; // this signals the cursor is at the end
  31. m_nFindFileIndex=0; // this indicates the position of FindFile, used for Clone()
  32. }
  33. CMDSPEnumStorage::~CMDSPEnumStorage()
  34. {
  35. if( m_hFFile !=INVALID_HANDLE_VALUE )
  36. {
  37. FindClose(m_hFFile);
  38. }
  39. }
  40. STDMETHODIMP CMDSPEnumStorage::Next(ULONG celt, IMDSPStorage * * ppStorage, ULONG * pceltFetched)
  41. {
  42. HRESULT hr=S_FALSE;
  43. CARg(ppStorage);
  44. CARg(pceltFetched);
  45. *pceltFetched = 0;
  46. if(m_nEndSearch)
  47. {
  48. return S_FALSE;
  49. }
  50. if ( wcslen(m_wcsPath) < 3 ) // For the root storage
  51. {
  52. CComObject<CMDSPStorage> *pStg;
  53. hr=CComObject<CMDSPStorage>::CreateInstance(&pStg);
  54. if( SUCCEEDED(hr) )
  55. {
  56. hr=pStg->QueryInterface(IID_IMDSPStorage, reinterpret_cast<void**>(ppStorage));
  57. if( FAILED(hr) )
  58. {
  59. delete pStg;
  60. *pceltFetched=0;
  61. }
  62. else
  63. {
  64. wcscpy(pStg->m_wcsName, m_wcsPath);
  65. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  66. {
  67. wcscat(pStg->m_wcsName, g_wcsBackslash);
  68. }
  69. m_nEndSearch = 1; // Signal end of enumeration
  70. }
  71. }
  72. if( SUCCEEDED(hr) ) // if obj created successfully
  73. {
  74. *pceltFetched=1;
  75. if( celt != 1 )
  76. {
  77. hr=S_FALSE; // didn't get what he wanted
  78. }
  79. }
  80. return hr;
  81. }
  82. // For non-root storage
  83. WCHAR wcsTmp[MAX_PATH];
  84. char szTmp[MAX_PATH];
  85. ULONG i;
  86. if( g_bIsWinNT )
  87. {
  88. WIN32_FIND_DATAW wfd;
  89. for(i=0; (i<celt)&&(!m_nEndSearch); )
  90. {
  91. if( m_hFFile == INVALID_HANDLE_VALUE )
  92. {
  93. wcscpy(wcsTmp, m_wcsPath);
  94. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  95. {
  96. wcscat(wcsTmp, g_wcsBackslash);
  97. }
  98. wcscat(wcsTmp, L"*");
  99. m_hFFile = FindFirstFileW(wcsTmp, &wfd);
  100. if( m_hFFile == INVALID_HANDLE_VALUE )
  101. {
  102. m_nEndSearch = 1;
  103. }
  104. else
  105. {
  106. m_nFindFileIndex=1;
  107. }
  108. }
  109. else
  110. {
  111. if( !FindNextFileW(m_hFFile, &wfd) )
  112. {
  113. m_nEndSearch = 1;
  114. }
  115. else
  116. {
  117. m_nFindFileIndex++;
  118. }
  119. }
  120. if ( !m_nEndSearch )
  121. {
  122. if( !wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L"..") || !wcsicmp(wfd.cFileName, L"PMP") )
  123. {
  124. continue;
  125. }
  126. CComObject<CMDSPStorage> *pStg;
  127. hr=CComObject<CMDSPStorage>::CreateInstance(&pStg);
  128. if( SUCCEEDED(hr) )
  129. {
  130. hr=pStg->QueryInterface(
  131. IID_IMDSPStorage,
  132. reinterpret_cast<void**>(&(ppStorage[*pceltFetched]))
  133. );
  134. if( FAILED(hr) )
  135. {
  136. delete pStg;
  137. }
  138. else
  139. {
  140. wcscpy(pStg->m_wcsName, m_wcsPath);
  141. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  142. {
  143. wcscat(pStg->m_wcsName, g_wcsBackslash);
  144. }
  145. wcscat(pStg->m_wcsName, wfd.cFileName);
  146. *pceltFetched = (*pceltFetched)+1;
  147. i++;
  148. }
  149. }
  150. }
  151. } // end of For loop
  152. }
  153. else
  154. { // On Win9x, use A-version of Win32 APIs
  155. WIN32_FIND_DATAA fd;
  156. for(i=0; (i<celt)&&(!m_nEndSearch); )
  157. {
  158. if( m_hFFile == INVALID_HANDLE_VALUE )
  159. {
  160. wcscpy(wcsTmp, m_wcsPath);
  161. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  162. {
  163. wcscat(wcsTmp, g_wcsBackslash);
  164. }
  165. wcscat(wcsTmp, L"*");
  166. WideCharToMultiByte(CP_ACP, NULL, wcsTmp, -1, szTmp, MAX_PATH, NULL, NULL);
  167. m_hFFile = FindFirstFileA(szTmp, &fd);
  168. if( m_hFFile == INVALID_HANDLE_VALUE )
  169. {
  170. m_nEndSearch = 1;
  171. }
  172. else
  173. {
  174. m_nFindFileIndex=1;
  175. }
  176. }
  177. else
  178. {
  179. if( !FindNextFileA(m_hFFile, &fd) )
  180. {
  181. m_nEndSearch = 1;
  182. }
  183. else
  184. {
  185. m_nFindFileIndex++;
  186. }
  187. }
  188. if ( !m_nEndSearch )
  189. {
  190. if( !strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..") || !stricmp(fd.cFileName, "PMP") )
  191. {
  192. continue;
  193. }
  194. CComObject<CMDSPStorage> *pStg;
  195. hr=CComObject<CMDSPStorage>::CreateInstance(&pStg);
  196. if( SUCCEEDED(hr) )
  197. {
  198. hr=pStg->QueryInterface(IID_IMDSPStorage, reinterpret_cast<void**>(&(ppStorage[*pceltFetched])));
  199. if( FAILED(hr) )
  200. {
  201. delete pStg;
  202. }
  203. else
  204. {
  205. wcscpy(pStg->m_wcsName, m_wcsPath);
  206. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  207. {
  208. wcscat(pStg->m_wcsName, g_wcsBackslash);
  209. }
  210. MultiByteToWideChar(CP_ACP, NULL, fd.cFileName, -1, wcsTmp, MAX_PATH);
  211. wcscat(pStg->m_wcsName, wcsTmp);
  212. *pceltFetched = (*pceltFetched)+1;
  213. i++;
  214. }
  215. }
  216. }
  217. } // end of For loop
  218. }
  219. if( SUCCEEDED(hr) && (*pceltFetched<celt) )
  220. {
  221. hr = S_FALSE;
  222. }
  223. Error:
  224. hrLogDWORD("IMDSPEnumStorage::Next returned 0x%08lx", hr, hr);
  225. return hr;
  226. }
  227. STDMETHODIMP CMDSPEnumStorage::Skip(ULONG celt, ULONG *pceltFetched)
  228. {
  229. HRESULT hr=S_OK;
  230. CARg(celt);
  231. CARg(pceltFetched);
  232. CFRg(!m_nEndSearch); // make sure it is not the end of list
  233. *pceltFetched = 0;
  234. if( wcslen(m_wcsPath) < 3 ) // do nothing if it is the root storage
  235. {
  236. return S_OK;
  237. }
  238. char szTmp[MAX_PATH];
  239. WCHAR wcsTmp[MAX_PATH];
  240. ULONG i;
  241. if( g_bIsWinNT )
  242. {
  243. WIN32_FIND_DATAW wfd;
  244. for(i=0; (i<celt)&&(!m_nEndSearch); )
  245. {
  246. if( m_hFFile==INVALID_HANDLE_VALUE ) // at the start
  247. {
  248. wcscpy(wcsTmp, m_wcsPath);
  249. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  250. {
  251. wcscat(wcsTmp, g_wcsBackslash);
  252. }
  253. wcscat(wcsTmp, L"*");
  254. m_hFFile = FindFirstFileW(wcsTmp, &wfd);
  255. if( m_hFFile == INVALID_HANDLE_VALUE )
  256. {
  257. m_nEndSearch = 1;
  258. }
  259. else
  260. {
  261. m_nFindFileIndex=1;
  262. }
  263. }
  264. else
  265. {
  266. if( !FindNextFileW(m_hFFile, &wfd) )
  267. {
  268. m_nEndSearch = 1;
  269. }
  270. else
  271. {
  272. m_nFindFileIndex++;
  273. }
  274. }
  275. if( !m_nEndSearch )
  276. {
  277. if( !wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L"..") || !wcsicmp(wfd.cFileName, L"PMP") )
  278. {
  279. continue;
  280. }
  281. *pceltFetched = (*pceltFetched)+1;
  282. i++;
  283. }
  284. }
  285. }
  286. else
  287. { // On Win9x, use A-version of Win32 APIs
  288. WIN32_FIND_DATAA fd;
  289. for(i=0; (i<celt)&&(!m_nEndSearch); )
  290. {
  291. if( m_hFFile==INVALID_HANDLE_VALUE ) // at the start
  292. {
  293. wcscpy(wcsTmp, m_wcsPath);
  294. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  295. {
  296. wcscat(wcsTmp, g_wcsBackslash);
  297. }
  298. wcscat(wcsTmp, L"*");
  299. WideCharToMultiByte(CP_ACP, NULL, wcsTmp, -1, szTmp, MAX_PATH, NULL, NULL);
  300. m_hFFile = FindFirstFileA(szTmp, &fd);
  301. if( m_hFFile == INVALID_HANDLE_VALUE )
  302. {
  303. m_nEndSearch = 1;
  304. }
  305. else
  306. {
  307. m_nFindFileIndex=1;
  308. }
  309. }
  310. else
  311. {
  312. if( !FindNextFileA(m_hFFile, &fd) )
  313. {
  314. m_nEndSearch = 1;
  315. }
  316. else
  317. {
  318. m_nFindFileIndex++;
  319. }
  320. }
  321. if( !m_nEndSearch )
  322. {
  323. if( !strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..") || !stricmp(fd.cFileName, "PMP") )
  324. {
  325. continue;
  326. }
  327. *pceltFetched = (*pceltFetched)+1;
  328. i++;
  329. }
  330. }
  331. }
  332. if( *pceltFetched < celt )
  333. {
  334. hr = S_FALSE;
  335. }
  336. Error:
  337. hrLogDWORD("IMDSPEnumStorage::Skip returned 0x%08lx", hr, hr);
  338. return hr;
  339. }
  340. STDMETHODIMP CMDSPEnumStorage::Reset()
  341. {
  342. HRESULT hr = S_OK;
  343. m_nEndSearch=0;
  344. if(m_hFFile && m_hFFile != INVALID_HANDLE_VALUE )
  345. {
  346. FindClose(m_hFFile);
  347. }
  348. m_hFFile = INVALID_HANDLE_VALUE;
  349. m_nFindFileIndex=0;
  350. hrLogDWORD("IMDSPEnumStorage::Reset returned 0x%08lx", hr, hr);
  351. return hr;
  352. }
  353. STDMETHODIMP CMDSPEnumStorage::Clone(IMDSPEnumStorage * * ppEnumStorage)
  354. {
  355. HRESULT hr=E_FAIL;
  356. CARg(ppEnumStorage);
  357. CComObject<CMDSPEnumStorage> *pEnumObj;
  358. CORg(CComObject<CMDSPEnumStorage>::CreateInstance(&pEnumObj));
  359. hr=pEnumObj->QueryInterface(IID_IMDSPEnumStorage, reinterpret_cast<void**>(ppEnumStorage));
  360. if( FAILED(hr) )
  361. {
  362. delete pEnumObj;
  363. }
  364. else
  365. {
  366. WCHAR wcsTmp[MAX_PATH];
  367. char szTmp[MAX_PATH];
  368. int i, nErrorEnd=0;
  369. wcscpy(pEnumObj->m_wcsPath, m_wcsPath);
  370. pEnumObj->m_nEndSearch = m_nEndSearch;
  371. pEnumObj->m_nFindFileIndex = m_nFindFileIndex;
  372. if( !(pEnumObj->m_nEndSearch) && (pEnumObj->m_nFindFileIndex) )
  373. // now Clone the FindFile state
  374. {
  375. if( g_bIsWinNT )
  376. {
  377. WIN32_FIND_DATAW wfd;
  378. for(i=0; (i<m_nFindFileIndex)&&(!nErrorEnd); )
  379. {
  380. if( pEnumObj->m_hFFile == INVALID_HANDLE_VALUE )
  381. {
  382. wcscpy(wcsTmp, m_wcsPath);
  383. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  384. {
  385. wcscat(wcsTmp, g_wcsBackslash);
  386. }
  387. wcscat(wcsTmp, L"*");
  388. pEnumObj->m_hFFile = FindFirstFileW(wcsTmp, &wfd);
  389. if( pEnumObj->m_hFFile == INVALID_HANDLE_VALUE )
  390. {
  391. nErrorEnd = 1;
  392. }
  393. else
  394. {
  395. i=1;
  396. }
  397. }
  398. else
  399. {
  400. if( !FindNextFileW(pEnumObj->m_hFFile, &wfd) )
  401. {
  402. nErrorEnd = 1;
  403. }
  404. else
  405. {
  406. i++;
  407. }
  408. }
  409. if ( !nErrorEnd )
  410. {
  411. if( !wcscmp(wfd.cFileName, L".") || !wcscmp(wfd.cFileName, L"..") || !wcsicmp(wfd.cFileName, L"PMP") )
  412. {
  413. continue;
  414. }
  415. }
  416. } // end of FOR loop
  417. } else {
  418. WIN32_FIND_DATAA fd;
  419. for(i=0; (i<m_nFindFileIndex)&&(!nErrorEnd); )
  420. {
  421. if( pEnumObj->m_hFFile == INVALID_HANDLE_VALUE )
  422. {
  423. wcscpy(wcsTmp, m_wcsPath);
  424. if( m_wcsPath[wcslen(m_wcsPath)-1] != 0x5c )
  425. {
  426. wcscat(wcsTmp, g_wcsBackslash);
  427. }
  428. wcscat(wcsTmp, L"*");
  429. WideCharToMultiByte(CP_ACP, NULL, wcsTmp, -1, szTmp, MAX_PATH, NULL, NULL);
  430. pEnumObj->m_hFFile = FindFirstFileA(szTmp, &fd);
  431. if( pEnumObj->m_hFFile == INVALID_HANDLE_VALUE )
  432. {
  433. nErrorEnd = 1;
  434. }
  435. else
  436. {
  437. i=1;
  438. }
  439. }
  440. else
  441. {
  442. if( !FindNextFileA(pEnumObj->m_hFFile, &fd) )
  443. {
  444. nErrorEnd = 1;
  445. }
  446. else
  447. {
  448. i++;
  449. }
  450. }
  451. if ( !nErrorEnd )
  452. {
  453. if( !strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..") || !stricmp( fd.cFileName, "PMP") )
  454. {
  455. continue;
  456. }
  457. }
  458. } // end of FOR loop
  459. }
  460. }
  461. if ( nErrorEnd )
  462. {
  463. hr = E_UNEXPECTED;
  464. }
  465. else
  466. {
  467. hr=S_OK;
  468. }
  469. }
  470. Error:
  471. hrLogDWORD("IMDSPEnumStorage::Clone returned 0x%08lx", hr, hr);
  472. return hr;
  473. }