windows-nt/Source/XPSP1/NT/shell/shell32/hwcmmn.cpp
2020-09-26 16:20:57 +08:00

374 lines
9.7 KiB
C++

#include "shellprv.h"
#include "ids.h"
#include "hwcmmn.h"
#include "mtptl.h"
HRESULT _GetAutoplayHandler(LPCWSTR pszDeviceID, LPCWSTR pszEventType,
LPCWSTR pszContentTypeHandler, IAutoplayHandler** ppiah)
{
HRESULT hr = CoCreateInstance(CLSID_HWEventSettings, NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_NO_FAILURE_LOG, IID_PPV_ARG(IAutoplayHandler, ppiah));
if (SUCCEEDED(hr))
{
hr = (*ppiah)->InitWithContent(pszDeviceID, pszEventType,
pszContentTypeHandler);
if (SUCCEEDED(hr))
{
hr = CoSetProxyBlanket((*ppiah),
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
}
if (FAILED(hr))
{
(*ppiah)->Release();
*ppiah = NULL;
}
}
return hr;
}
HRESULT _GetAutoplayHandlerNoContent(LPCWSTR pszDeviceID, LPCWSTR pszEventType,
IAutoplayHandler** ppiah)
{
HRESULT hr = CoCreateInstance(CLSID_HWEventSettings, NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_NO_FAILURE_LOG, IID_PPV_ARG(IAutoplayHandler, ppiah));
if (SUCCEEDED(hr))
{
hr = (*ppiah)->Init(pszDeviceID, pszEventType);
if (SUCCEEDED(hr))
{
hr = CoSetProxyBlanket((*ppiah),
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
}
if (FAILED(hr))
{
(*ppiah)->Release();
*ppiah = NULL;
}
}
return hr;
}
HRESULT _GetHWDevice(LPCWSTR pszDeviceID, IHWDevice** ppihwdevice)
{
HRESULT hr = CoCreateInstance(CLSID_HWDevice, NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_NO_FAILURE_LOG, IID_PPV_ARG(IHWDevice, ppihwdevice));
if (SUCCEEDED(hr))
{
hr = (*ppihwdevice)->Init(pszDeviceID);
if (FAILED(hr))
{
(*ppihwdevice)->Release();
*ppihwdevice = NULL;
}
}
return hr;
}
HICON _GetIconFromIconLocation(LPCWSTR pszIconLocation, BOOL fBigIcon)
{
WCHAR szIconLocation[MAX_PATH + 12];
HIMAGELIST himagelist;
int iImage;
Shell_GetImageLists(fBigIcon ? &himagelist : NULL, fBigIcon ? NULL : &himagelist);
lstrcpyn(szIconLocation, pszIconLocation, ARRAYSIZE(szIconLocation));
iImage = Shell_GetCachedImageIndex(szIconLocation,
PathParseIconLocation(szIconLocation), 0);
return ImageList_GetIcon(himagelist, iImage, ILD_TRANSPARENT);
}
HRESULT _GetHardwareDevices(IHardwareDevices** ppihwdevices)
{
return CoCreateInstance(CLSID_HardwareDevices, NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_NO_FAILURE_LOG, IID_PPV_ARG(IHardwareDevices, ppihwdevices));
}
BOOL IsShellServiceRunning()
{
BOOL fRunning = FALSE;
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (hSCM)
{
SC_HANDLE hService = OpenService(hSCM, TEXT("ShellHWDetection"),
SERVICE_INTERROGATE);
if (hService)
{
SERVICE_STATUS ss;
if (ControlService(hService, SERVICE_CONTROL_INTERROGATE, &ss))
{
if (SERVICE_RUNNING == ss.dwCurrentState)
{
fRunning = TRUE;
}
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCM);
}
return fRunning;
}
STDAPI GetDeviceProperties(LPCWSTR pszDeviceID, IHWDeviceCustomProperties **ppdcp)
{
HRESULT hr = CoCreateInstance(CLSID_HWDeviceCustomProperties, NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_NO_FAILURE_LOG, IID_PPV_ARG(IHWDeviceCustomProperties, ppdcp));
if (SUCCEEDED(hr))
{
BOOL fVolumeFlag = TRUE;
const TCHAR cszDeviceHeader[] = TEXT("\\\\?\\");
if (!StrCmpN(cszDeviceHeader, pszDeviceID, ARRAYSIZE(cszDeviceHeader) - 1))
{
fVolumeFlag = CMtPtLocal::IsVolume(pszDeviceID);
}
hr = (*ppdcp)->InitFromDeviceID(pszDeviceID, fVolumeFlag ? HWDEVCUSTOMPROP_USEVOLUMEPROCESSING : 0);
if (FAILED(hr))
{
(*ppdcp)->Release();
*ppdcp = NULL;
}
}
return hr;
}
struct CONTENTTYPEINFO
{
DWORD dwContentType;
LPCWSTR pszContentTypeHandler;
int iContentTypeFriendlyName;
LPCWSTR pszContentTypeIconLocation;
};
static const CONTENTTYPEINFO contenttypeinfo[] =
{
{ CT_CDAUDIO , TEXT("CDAudioContentHandler"), IDS_AP_CDAUDIOCONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shell32.dll,-228") },
{ CT_DVDMOVIE , TEXT("DVDMovieContentHandler"), IDS_AP_DVDMOVIECONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shell32.dll,-222") },
{ CT_BLANKCDRW , TEXT("BlankCDContentHandler"), IDS_AP_BLANKCDCONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shell32.dll,-260") },
{ CT_BLANKCDR , TEXT("BlankCDContentHandler"), IDS_AP_BLANKCDCONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shell32.dll,-260") },
{ CT_AUTOPLAYMUSIC , TEXT("MusicFilesContentHandler"), IDS_AP_MUSICFILESCONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shell32.dll,-225") },
{ CT_AUTOPLAYPIX , TEXT("PicturesContentHandler"), IDS_AP_PICTURESCONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shimgvw.dll,3") },
{ CT_AUTOPLAYMOVIE , TEXT("VideoFilesContentHandler"), IDS_AP_VIDEOFILESCONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shell32.dll,-224") },
{ CT_AUTOPLAYMIXEDCONTENT, TEXT("MixedContentHandler"), IDS_AP_MIXEDCONTENTCONTENTHANDLER,
TEXT("%SystemRoot%\\system32\\shell32.dll,-227") },
{ CT_AUTORUNINF , NULL, 0, NULL },
{ CT_UNKNOWNCONTENT , NULL, 0, NULL },
{ CT_BLANKDVDR , NULL, 0, NULL },
{ CT_BLANKDVDRW , NULL, 0, NULL },
};
HRESULT _GetContentTypeInfo(DWORD dwContentType, LPWSTR pszContentTypeFriendlyName,
DWORD cchContentTypeFriendlyName, LPWSTR pszContentTypeIconLocation,
DWORD cchContentTypeIconLocation)
{
HRESULT hr = E_FAIL;
for (DWORD dw = 0; dw < ARRAYSIZE(contenttypeinfo); ++dw)
{
//
// First matching entry wins.
//
if (contenttypeinfo[dw].dwContentType & dwContentType)
{
ASSERT(contenttypeinfo[dw].pszContentTypeHandler);
if (!LoadString(g_hinst, contenttypeinfo[dw].iContentTypeFriendlyName,
pszContentTypeFriendlyName, cchContentTypeFriendlyName))
{
*pszContentTypeFriendlyName = 0;
}
StrCpyN(pszContentTypeIconLocation, contenttypeinfo[dw].pszContentTypeIconLocation,
cchContentTypeIconLocation);
hr = S_OK;
break;
}
}
return hr;
}
BOOL IsMixedContent(DWORD dwContentType)
{
BOOL fRet;
switch (CT_ANYAUTOPLAYCONTENT & dwContentType)
{
case 0:
case CT_AUTOPLAYMUSIC:
case CT_AUTOPLAYPIX:
case CT_AUTOPLAYMOVIE:
fRet = FALSE;
break;
default:
fRet = TRUE;
break;
}
return fRet;
}
HRESULT _GetContentTypeHandler(DWORD dwContentType, LPWSTR pszContentTypeHandler,
DWORD cchContentTypeHandler)
{
HRESULT hr = E_FAIL;
if (IsMixedContent(dwContentType))
{
StrCpyN(pszContentTypeHandler, TEXT("MixedContentHandler"), cchContentTypeHandler);
hr = S_OK;
}
else
{
for (DWORD dw = 0; dw < ARRAYSIZE(contenttypeinfo); ++dw)
{
//
// First matching entry wins.
//
if (contenttypeinfo[dw].dwContentType & dwContentType)
{
StrCpyN(pszContentTypeHandler, contenttypeinfo[dw].pszContentTypeHandler,
cchContentTypeHandler);
hr = S_OK;
break;
}
}
}
return hr;
}
HRESULT _GetHandlerInvokeProgIDAndVerb(LPCWSTR pszHandler, LPWSTR pszInvokeProgID,
DWORD cchInvokeProgID, LPWSTR pszInvokeVerb, DWORD cchInvokeVerb)
{
IAutoplayHandlerProperties* pahp;
HRESULT hr = CoCreateInstance(CLSID_AutoplayHandlerProperties, NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_NO_FAILURE_LOG,
IID_PPV_ARG(IAutoplayHandlerProperties, &pahp));
if (SUCCEEDED(hr))
{
hr = pahp->Init(pszHandler);
if (SUCCEEDED(hr))
{
LPWSTR pszInvokeProgIDLocal;
LPWSTR pszInvokeVerbLocal;
hr = pahp->GetInvokeProgIDAndVerb(&pszInvokeProgIDLocal, &pszInvokeVerbLocal);
if (SUCCEEDED(hr))
{
lstrcpyn(pszInvokeProgID, pszInvokeProgIDLocal, cchInvokeProgID);
lstrcpyn(pszInvokeVerb, pszInvokeVerbLocal, cchInvokeVerb);
CoTaskMemFree(pszInvokeProgIDLocal);
CoTaskMemFree(pszInvokeVerbLocal);
}
}
pahp->Release();
}
return hr;
}
//
CCrossThreadFlag::~CCrossThreadFlag()
{
TraceMsg(TF_MOUNTPOINT, "AUTOPLAY: CCrossThreadFlag::~CCrossThreadFlag called");
if (_hEvent)
{
CloseHandle(_hEvent);
}
}
BOOL CCrossThreadFlag::Init()
{
ASSERT(!_fInited);
_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
#ifdef DEBUG
if (_hEvent)
{
_fInited = TRUE;
}
#endif
return !!_hEvent;
}
BOOL CCrossThreadFlag::Signal()
{
ASSERT(_fInited);
TraceMsg(TF_MOUNTPOINT, "AUTOPLAY: CCrossThreadFlag::Signal called");
return SetEvent(_hEvent);
}
BOOL CCrossThreadFlag::IsSignaled()
{
ASSERT(_fInited);
BOOL fRet = (WAIT_OBJECT_0 == WaitForSingleObject(_hEvent, 0));
TraceMsg(TF_MOUNTPOINT, "AUTOPLAY: CCrossThreadFlag::IsSignaled called: %d", fRet);
return fRet;
}