// // Microsoft Windows Media Technologies // Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved. // // MSHDSP.DLL is a sample WMDM Service Provider(SP) that enumerates fixed drives. // This sample shows you how to implement an SP according to the WMDM documentation. // This sample uses fixed drives on your PC to emulate portable media, and // shows the relationship between different interfaces and objects. Each hard disk // volume is enumerated as a device and directories and files are enumerated as // Storage objects under respective devices. You can copy non-SDMI compliant content // to any device that this SP enumerates. To copy an SDMI compliant content to a // device, the device must be able to report a hardware embedded serial number. // Hard disks do not have such serial numbers. // // To build this SP, you are recommended to use the MSHDSP.DSP file under Microsoft // Visual C++ 6.0 and run REGSVR32.EXE to register the resulting MSHDSP.DLL. You can // then build the sample application from the WMDMAPP directory to see how it gets // loaded by the application. However, you need to obtain a certificate from // Microsoft to actually run this SP. This certificate would be in the KEY.C file // under the INCLUDE directory for one level up. //*************************************************************************** // // Name: MDSPutil.cpp // // Description: Utility functions for MDSP // //*************************************************************************** #include "hdspPCH.h" #include "wmsstd.h" #define STRSAFE_NO_DEPRECATE #include "strsafe.h" HRESULT __stdcall UtilGetSerialNumber(WCHAR *wcsDeviceName, PWMDMID pSerialNumber, BOOL fCreate) { /* // TO TEST RETURNING A SERIAL NUMBER, UNCOMMENT THIS SECTION. // if( 1 ) { BYTE DEF_HDID[20] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}; pSerialNumber->dwVendorID = 0xFFFF; memcpy( (pSerialNumber->pID), DEF_HDID, sizeof(DEF_HDID) ); pSerialNumber->SerialNumberLength = 20; return S_OK; } else */ { return WMDM_E_NOTSUPPORTED; } } UINT __stdcall UtilGetDriveType(LPSTR szDL) { return GetDriveType( szDL ); } HRESULT __stdcall UtilGetManufacturer(LPWSTR pDeviceName, LPWSTR *ppwszName, UINT nMaxChars) { static const WCHAR* wszUnknown = L"Unknown"; if (nMaxChars > wcslen(wszUnknown)) { wcscpy( *ppwszName, wszUnknown); return S_OK; } else { return STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h } } HRESULT wcsParseDeviceName(WCHAR *wcsIn, WCHAR *wcsOut, DWORD dwOutBufSizeInChars) { WCHAR wcsTmp[MAX_PATH], *pWcs; HRESULT hr; hr = StringCchCopyW(wcsTmp, ARRAYSIZE(wcsTmp), wcsIn); if (FAILED(hr)) { return hr; } pWcs = wcschr(wcsTmp, 0x5c); if( pWcs ) *pWcs=0; if (wcslen(wcsTmp) < dwOutBufSizeInChars) { wcscpy(wcsOut, wcsTmp); } else { return STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h } return S_OK; } HRESULT GetFileSizeRecursive(char *szPath, DWORD *pdwSizeLow, DWORD *pdwSizeHigh) { HRESULT hr = S_OK; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hFindFile = INVALID_HANDLE_VALUE; DWORD dwSizeLow = 0; DWORD dwSizeHigh = 0; WIN32_FIND_DATAA fd; char szLP[MAX_PATH+BACKSLASH_SZ_STRING_LENGTH+1]; CARg( szPath ); CARg( pdwSizeLow ); CARg( pdwSizeHigh ); CARg(szPath[0]); // strcpy( szLP, szPath ); hr = StringCchCopyA(szLP, ARRAYSIZE(szLP)-BACKSLASH_SZ_STRING_LENGTH-1, szPath); if (FAILED(hr)) { goto Error; } DWORD dwAttrib = GetFileAttributesA(szPath); if (dwAttrib == INVALID_FILE_ATTRIBUTES) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Error; } if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib ) { if( szLP[strlen(szLP)-1] != 0x5c ) { strcat(szLP, g_szBackslash); } strcat(szLP, "*"); hFindFile = FindFirstFileA(szLP, &fd); if( hFindFile != INVALID_HANDLE_VALUE ) { if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") ) { szLP[strlen(szLP)-1] = 0; // erase the '*' // strcat(szLP, fd.cFileName); CORg(StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName)); CORg(GetFileSizeRecursive(szLP, pdwSizeLow, pdwSizeHigh)); } while ( FindNextFileA(hFindFile, &fd) ) { if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") ) { strcpy(szLP, szPath); if( szLP[strlen(szLP)-1] != 0x5c ) { strcat(szLP, g_szBackslash); } // strcat(szLP, fd.cFileName); CORg(StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName)); CORg(GetFileSizeRecursive(szLP, pdwSizeLow, pdwSizeHigh)); } } hr = GetLastError(); if( hr == ERROR_NO_MORE_FILES ) { hr = S_OK; } else { hr = HRESULT_FROM_WIN32(hr); } } } else { hFile = CreateFileA( szPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); CWRg(hFile != INVALID_HANDLE_VALUE); dwSizeLow = GetFileSize(hFile, &dwSizeHigh); if (dwSizeLow == INVALID_FILE_SIZE) { DWORD dwLastError = GetLastError(); if (dwLastError != NO_ERROR) { hr = HRESULT_FROM_WIN32(dwLastError); CloseHandle(hFile); goto Error; } } CloseHandle(hFile); unsigned _int64 u64Size = ((unsigned _int64) dwSizeHigh << 32) | dwSizeLow; u64Size += *pdwSizeLow | ((unsigned _int64) (*pdwSizeHigh) << 32 ); *pdwSizeLow = (DWORD) (u64Size & 0xFFFFFFFF); *pdwSizeHigh = (DWORD) (u64Size >> 32); hr = S_OK; } Error: if( hFindFile != INVALID_HANDLE_VALUE ) { FindClose(hFindFile); } return hr; } HRESULT DeleteFileRecursive(char *szPath) { HRESULT hr=S_OK; CARg(szPath); CARg(szPath[0]); DWORD dwAttrib = GetFileAttributesA(szPath); if (dwAttrib == INVALID_FILE_ATTRIBUTES) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Error; } if( FILE_ATTRIBUTE_DIRECTORY & dwAttrib ) { HANDLE hFindFile = INVALID_HANDLE_VALUE; WIN32_FIND_DATAA fd; char szLP[MAX_PATH+BACKSLASH_SZ_STRING_LENGTH+1]; // strcpy(szLP, szPath); hr = StringCchCopyA(szLP, ARRAYSIZE(szLP)-BACKSLASH_SZ_STRING_LENGTH-1, szPath); if (FAILED(hr)) { goto Error; } if( szLP[strlen(szLP)-1] != 0x5c ) { strcat(szLP, g_szBackslash); } strcat(szLP, "*"); hFindFile = FindFirstFileA(szLP, &fd); if ( hFindFile != INVALID_HANDLE_VALUE ) { do { if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") ) { strcpy(szLP, szPath); if( szLP[strlen(szLP)-1] != 0x5c ) { strcat(szLP, g_szBackslash); } // strcat(szLP, fd.cFileName); hr = StringCchCatA(szLP, ARRAYSIZE(szLP), fd.cFileName); if (FAILED(hr)) { FindClose(hFindFile); CHRg(hr); } // CHRg(DeleteFileRecursive(szLP)); hr = DeleteFileRecursive(szLP); if (FAILED(hr)) { FindClose(hFindFile); CHRg(hr); } } } while ( FindNextFileA(hFindFile, &fd) ) ; hr = GetLastError(); FindClose(hFindFile); } else { hr = GetLastError(); } // Until here this dir should be empty if( hr == ERROR_NO_MORE_FILES ) { CWRg(RemoveDirectory(szPath)); hr = S_OK; } else { hr = HRESULT_FROM_WIN32(hr); } } else { CWRg( DeleteFileA(szPath) ); } Error: return hr; } HRESULT SetGlobalDeviceStatus(WCHAR *wcsNameIn, DWORD dwStat, BOOL bClear) { HRESULT hr = S_OK; WCHAR wcsName[32]; WCHAR *pWN; int i; g_CriticalSection.Lock(); CARg(wcsNameIn); pWN = &wcsName[0]; HRESULT hrTemp = wcsParseDeviceName(wcsNameIn, pWN, ARRAYSIZE(wcsName)); if (FAILED(hrTemp)) { hr = hrTemp; goto Error; } // Search for existing entries to see if there is a match // for( i=0; i