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.

428 lines
11 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
  4. //
  5. // MSHDSP.DLL is a sample WMDM Service Provider(SP) that enumerates fixed drives.
  6. // This sample shows you how to implement an SP according to the WMDM documentation.
  7. // This sample uses fixed drives on your PC to emulate portable media, and
  8. // shows the relationship between different interfaces and objects. Each hard disk
  9. // volume is enumerated as a device and directories and files are enumerated as
  10. // Storage objects under respective devices. You can copy non-SDMI compliant content
  11. // to any device that this SP enumerates. To copy an SDMI compliant content to a
  12. // device, the device must be able to report a hardware embedded serial number.
  13. // Hard disks do not have such serial numbers.
  14. //
  15. // To build this SP, you are recommended to use the MSHDSP.DSP file under Microsoft
  16. // Visual C++ 6.0 and run REGSVR32.EXE to register the resulting MSHDSP.DLL. You can
  17. // then build the sample application from the WMDMAPP directory to see how it gets
  18. // loaded by the application. However, you need to obtain a certificate from
  19. // Microsoft to actually run this SP. This certificate would be in the KEY.C file
  20. // under the INCLUDE directory for one level up.
  21. //***************************************************************************
  22. //
  23. // Name: MDSPutil.cpp
  24. //
  25. // Description: Utility functions for MDSP
  26. //
  27. //***************************************************************************
  28. #include "hdspPCH.h"
  29. #include "wmsstd.h"
  30. #define STRSAFE_NO_DEPRECATE
  31. #include "strsafe.h"
  32. HRESULT __stdcall UtilGetSerialNumber(WCHAR *wcsDeviceName, PWMDMID pSerialNumber, BOOL fCreate)
  33. {
  34. /*
  35. // TO TEST RETURNING A SERIAL NUMBER, UNCOMMENT THIS SECTION.
  36. //
  37. if( 1 )
  38. {
  39. BYTE DEF_HDID[20] = {
  40. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  41. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
  42. pSerialNumber->dwVendorID = 0xFFFF;
  43. memcpy( (pSerialNumber->pID), DEF_HDID, sizeof(DEF_HDID) );
  44. pSerialNumber->SerialNumberLength = 20;
  45. return S_OK;
  46. }
  47. else
  48. */
  49. {
  50. return WMDM_E_NOTSUPPORTED;
  51. }
  52. }
  53. UINT __stdcall UtilGetDriveType(LPSTR szDL)
  54. {
  55. return GetDriveType( szDL );
  56. }
  57. HRESULT __stdcall UtilGetManufacturer(LPWSTR pDeviceName, LPWSTR *ppwszName, UINT nMaxChars)
  58. {
  59. static const WCHAR* wszUnknown = L"Unknown";
  60. if (nMaxChars > wcslen(wszUnknown))
  61. {
  62. wcscpy( *ppwszName, wszUnknown);
  63. return S_OK;
  64. }
  65. else
  66. {
  67. return STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  68. }
  69. }
  70. HRESULT wcsParseDeviceName(WCHAR *wcsIn, WCHAR *wcsOut, DWORD dwOutBufSizeInChars)
  71. {
  72. WCHAR wcsTmp[MAX_PATH], *pWcs;
  73. HRESULT hr;
  74. hr = StringCchCopyW(wcsTmp, ARRAYSIZE(wcsTmp), wcsIn);
  75. if (FAILED(hr))
  76. {
  77. return hr;
  78. }
  79. pWcs = wcschr(wcsTmp, 0x5c);
  80. if( pWcs ) *pWcs=0;
  81. if (wcslen(wcsTmp) < dwOutBufSizeInChars)
  82. {
  83. wcscpy(wcsOut, wcsTmp);
  84. }
  85. else
  86. {
  87. return STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  88. }
  89. return S_OK;
  90. }
  91. HRESULT GetFileSizeRecursive(char *szPath, DWORD *pdwSizeLow, DWORD *pdwSizeHigh)
  92. {
  93. HRESULT hr = S_OK;
  94. HANDLE hFile = INVALID_HANDLE_VALUE;
  95. HANDLE hFindFile = INVALID_HANDLE_VALUE;
  96. DWORD dwSizeLow = 0;
  97. DWORD dwSizeHigh = 0;
  98. WIN32_FIND_DATAA fd;
  99. char szLP[MAX_PATH+BACKSLASH_SZ_STRING_LENGTH+1];
  100. CARg( szPath );
  101. CARg( pdwSizeLow );
  102. CARg( pdwSizeHigh );
  103. CARg(szPath[0]);
  104. // strcpy( szLP, szPath );
  105. hr = StringCchCopyA(szLP, ARRAYSIZE(szLP)-BACKSLASH_SZ_STRING_LENGTH-1, szPath);
  106. if (FAILED(hr))
  107. {
  108. goto Error;
  109. }
  110. DWORD dwAttrib = GetFileAttributesA(szPath);
  111. if (dwAttrib == INVALID_FILE_ATTRIBUTES)
  112. {
  113. hr = HRESULT_FROM_WIN32(GetLastError());
  114. goto Error;
  115. }
  116. if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib )
  117. {
  118. if( szLP[strlen(szLP)-1] != 0x5c )
  119. {
  120. strcat(szLP, g_szBackslash);
  121. }
  122. strcat(szLP, "*");
  123. hFindFile = FindFirstFileA(szLP, &fd);
  124. if( hFindFile != INVALID_HANDLE_VALUE )
  125. {
  126. if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
  127. {
  128. szLP[strlen(szLP)-1] = 0; // erase the '*'
  129. // strcat(szLP, fd.cFileName);
  130. CORg(StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName));
  131. CORg(GetFileSizeRecursive(szLP, pdwSizeLow, pdwSizeHigh));
  132. }
  133. while ( FindNextFileA(hFindFile, &fd) )
  134. {
  135. if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
  136. {
  137. strcpy(szLP, szPath);
  138. if( szLP[strlen(szLP)-1] != 0x5c )
  139. {
  140. strcat(szLP, g_szBackslash);
  141. }
  142. // strcat(szLP, fd.cFileName);
  143. CORg(StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName));
  144. CORg(GetFileSizeRecursive(szLP, pdwSizeLow, pdwSizeHigh));
  145. }
  146. }
  147. hr = GetLastError();
  148. if( hr == ERROR_NO_MORE_FILES )
  149. {
  150. hr = S_OK;
  151. }
  152. else
  153. {
  154. hr = HRESULT_FROM_WIN32(hr);
  155. }
  156. }
  157. }
  158. else
  159. {
  160. hFile = CreateFileA(
  161. szPath,
  162. GENERIC_READ,
  163. FILE_SHARE_READ | FILE_SHARE_WRITE,
  164. NULL,
  165. OPEN_EXISTING,
  166. 0,
  167. NULL
  168. );
  169. CWRg(hFile != INVALID_HANDLE_VALUE);
  170. dwSizeLow = GetFileSize(hFile, &dwSizeHigh);
  171. if (dwSizeLow == INVALID_FILE_SIZE)
  172. {
  173. DWORD dwLastError = GetLastError();
  174. if (dwLastError != NO_ERROR)
  175. {
  176. hr = HRESULT_FROM_WIN32(dwLastError);
  177. CloseHandle(hFile);
  178. goto Error;
  179. }
  180. }
  181. CloseHandle(hFile);
  182. unsigned _int64 u64Size = ((unsigned _int64) dwSizeHigh << 32) |
  183. dwSizeLow;
  184. u64Size += *pdwSizeLow | ((unsigned _int64) (*pdwSizeHigh) << 32
  185. );
  186. *pdwSizeLow = (DWORD) (u64Size & 0xFFFFFFFF);
  187. *pdwSizeHigh = (DWORD) (u64Size >> 32);
  188. hr = S_OK;
  189. }
  190. Error:
  191. if( hFindFile != INVALID_HANDLE_VALUE )
  192. {
  193. FindClose(hFindFile);
  194. }
  195. return hr;
  196. }
  197. HRESULT DeleteFileRecursive(char *szPath)
  198. {
  199. HRESULT hr=S_OK;
  200. CARg(szPath);
  201. CARg(szPath[0]);
  202. DWORD dwAttrib = GetFileAttributesA(szPath);
  203. if (dwAttrib == INVALID_FILE_ATTRIBUTES)
  204. {
  205. hr = HRESULT_FROM_WIN32(GetLastError());
  206. goto Error;
  207. }
  208. if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib )
  209. {
  210. HANDLE hFindFile = INVALID_HANDLE_VALUE;
  211. WIN32_FIND_DATAA fd;
  212. char szLP[MAX_PATH+BACKSLASH_SZ_STRING_LENGTH+1];
  213. // strcpy(szLP, szPath);
  214. hr = StringCchCopyA(szLP, ARRAYSIZE(szLP)-BACKSLASH_SZ_STRING_LENGTH-1, szPath);
  215. if (FAILED(hr))
  216. {
  217. goto Error;
  218. }
  219. if( szLP[strlen(szLP)-1] != 0x5c )
  220. {
  221. strcat(szLP, g_szBackslash);
  222. }
  223. strcat(szLP, "*");
  224. hFindFile = FindFirstFileA(szLP, &fd);
  225. if ( hFindFile != INVALID_HANDLE_VALUE )
  226. {
  227. do {
  228. if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
  229. {
  230. strcpy(szLP, szPath);
  231. if( szLP[strlen(szLP)-1] != 0x5c )
  232. {
  233. strcat(szLP, g_szBackslash);
  234. }
  235. // strcat(szLP, fd.cFileName);
  236. hr = StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName);
  237. if (FAILED(hr))
  238. {
  239. FindClose(hFindFile);
  240. CHRg(hr);
  241. }
  242. // CHRg(DeleteFileRecursive(szLP));
  243. hr = DeleteFileRecursive(szLP);
  244. if (FAILED(hr))
  245. {
  246. FindClose(hFindFile);
  247. CHRg(hr);
  248. }
  249. }
  250. } while ( FindNextFileA(hFindFile, &fd) ) ;
  251. hr = GetLastError();
  252. FindClose(hFindFile);
  253. }
  254. else
  255. {
  256. hr = GetLastError();
  257. }
  258. // Until here this dir should be empty
  259. if( hr == ERROR_NO_MORE_FILES )
  260. {
  261. CWRg(RemoveDirectory(szPath));
  262. hr = S_OK;
  263. }
  264. else
  265. {
  266. hr = HRESULT_FROM_WIN32(hr);
  267. }
  268. }
  269. else
  270. {
  271. CWRg( DeleteFileA(szPath) );
  272. }
  273. Error:
  274. return hr;
  275. }
  276. HRESULT SetGlobalDeviceStatus(WCHAR *wcsNameIn, DWORD dwStat, BOOL bClear)
  277. {
  278. HRESULT hr = S_OK;
  279. WCHAR wcsName[32];
  280. WCHAR *pWN;
  281. int i;
  282. g_CriticalSection.Lock();
  283. CARg(wcsNameIn);
  284. pWN = &wcsName[0];
  285. HRESULT hrTemp = wcsParseDeviceName(wcsNameIn, pWN, ARRAYSIZE(wcsName));
  286. if (FAILED(hrTemp))
  287. {
  288. hr = hrTemp;
  289. goto Error;
  290. }
  291. // Search for existing entries to see if there is a match
  292. //
  293. for( i=0; i<MDSP_MAX_DEVICE_OBJ; i++ )
  294. {
  295. if( g_GlobalDeviceInfo[i].bValid )
  296. {
  297. if(!wcscmp(wcsName, g_GlobalDeviceInfo[i].wcsDevName) )
  298. {
  299. if( bClear )
  300. {
  301. g_GlobalDeviceInfo[i].dwStatus = dwStat;
  302. }
  303. else
  304. {
  305. g_GlobalDeviceInfo[i].dwStatus |= dwStat;
  306. }
  307. break; // a match has been found;
  308. }
  309. }
  310. }
  311. if( !(i<MDSP_MAX_DEVICE_OBJ) ) // new entry
  312. {
  313. for(i=0; i<MDSP_MAX_DEVICE_OBJ; i++)
  314. {
  315. if( !(g_GlobalDeviceInfo[i].bValid) ) // found empty space
  316. {
  317. wcscpy(g_GlobalDeviceInfo[i].wcsDevName, wcsName);
  318. g_GlobalDeviceInfo[i].bValid = TRUE;
  319. g_GlobalDeviceInfo[i].dwStatus = dwStat;
  320. break;
  321. }
  322. }
  323. }
  324. if( i<MDSP_MAX_DEVICE_OBJ )
  325. {
  326. hr = S_OK;
  327. }
  328. else
  329. {
  330. hr = hrNoMem;
  331. }
  332. Error:
  333. g_CriticalSection.Unlock();
  334. return hr;
  335. }
  336. HRESULT GetGlobalDeviceStatus(WCHAR *wcsNameIn, DWORD *pdwStat)
  337. {
  338. HRESULT hr = S_OK;
  339. WCHAR wcsName[32];
  340. WCHAR *pWN;
  341. int i;
  342. CARg(wcsNameIn);
  343. pWN = &wcsName[0];
  344. hr = wcsParseDeviceName(wcsNameIn, pWN, ARRAYSIZE(wcsName));
  345. if (FAILED(hr))
  346. {
  347. goto Error;
  348. }
  349. // Search for existing entries to see if there is a match
  350. //
  351. for( i=0; i<MDSP_MAX_DEVICE_OBJ; i++ )
  352. {
  353. if( g_GlobalDeviceInfo[i].bValid )
  354. {
  355. if(!wcscmp(wcsName, g_GlobalDeviceInfo[i].wcsDevName) )
  356. {
  357. *pdwStat = g_GlobalDeviceInfo[i].dwStatus;
  358. break; // a match has been found;
  359. }
  360. }
  361. }
  362. if( i<MDSP_MAX_DEVICE_OBJ )
  363. {
  364. hr = S_OK;
  365. }
  366. else
  367. {
  368. hr = E_FAIL;
  369. }
  370. Error:
  371. return hr;
  372. }