📄 device.cpp
字号:
{
HRESULT hres = STI_OK;
return hres;
}
STDMETHODIMP UsdSampDevice::UnLockDevice( VOID )
{
HRESULT hres = STI_OK;
return hres;
}
STDMETHODIMP UsdSampDevice::RawReadData( LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
HRESULT hres = STI_OK;
BOOL fRet = FALSE;
DWORD dwBytesReturned = 0;
if (INVALID_HANDLE_VALUE != m_DeviceDataHandle)
{
m_dwLastOperationError = NOERROR;
fRet = ::ReadFile(m_DeviceDataHandle,
lpBuffer,
*lpdwNumberOfBytes,
lpdwNumberOfBytes,
lpOverlapped);
if (!fRet) {
m_dwLastOperationError = ::GetLastError();
}
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
return hres;
}
STDMETHODIMP UsdSampDevice::RawWriteData( LPVOID lpBuffer, DWORD dwNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
HRESULT hres = STI_OK;
BOOL fRet = FALSE;;
DWORD dwBytesReturned = 0;
if (INVALID_HANDLE_VALUE != m_DeviceDataHandle)
{
fRet = ::WriteFile(m_DeviceDataHandle,
lpBuffer,
dwNumberOfBytes,
&dwBytesReturned,
lpOverlapped);
if (!fRet) {
m_dwLastOperationError = ::GetLastError();
}
hres = HRESULT_FROM_WIN32(m_dwLastOperationError);
}
else
{
hres = STIERR_NOT_INITIALIZED;
}
return hres;
}
STDMETHODIMP UsdSampDevice::RawReadCommand( LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
HRESULT hres = STIERR_UNSUPPORTED;
return hres;
}
STDMETHODIMP UsdSampDevice::RawWriteCommand( LPVOID lpBuffer, DWORD nNumberOfBytes,
LPOVERLAPPED lpOverlapped )
{
HRESULT hres = STIERR_UNSUPPORTED;
return hres;
}
STDMETHODIMP UsdSampDevice::Initialize( PSTIDEVICECONTROL pDcb, DWORD dwStiVersion,
HKEY hParametersKey )
{
HRESULT hres = STI_OK;
UINT uiNameLen = 0;
WCHAR szDeviceNameW[MAX_PATH];
if (!pDcb) {
return STIERR_INVALID_PARAM;
}
*szDeviceNameW = L'\0';
// Check STI specification version number
m_pDcb = pDcb;
m_pDcb->AddRef();
// Get the name of the device port we need to open
hres = m_pDcb->GetMyDevicePortName(szDeviceNameW,sizeof(szDeviceNameW)/sizeof(WCHAR));
if (!SUCCEEDED(hres) || !*szDeviceNameW) {
return hres;
}
// Convert name to SBCS
uiNameLen = WideCharToMultiByte(CP_ACP, 0, szDeviceNameW, -1, NULL, NULL, 0, 0);
if (!uiNameLen) {
return STIERR_INVALID_PARAM;
}
m_pszDeviceNameA = new CHAR[uiNameLen+1];
if (!m_pszDeviceNameA) {
return STIERR_INVALID_PARAM;
}
WideCharToMultiByte(CP_ACP, 0, szDeviceNameW, -1, m_pszDeviceNameA, uiNameLen, 0, 0);
//
// Open device ourselves
//
m_DeviceDataHandle = CreateFileA( m_pszDeviceNameA,
GENERIC_READ , // Access mask
FILE_SHARE_READ | FILE_SHARE_WRITE, // Share mode
NULL, // SA
OPEN_EXISTING, // Create disposition
FILE_ATTRIBUTE_SYSTEM, // Attributes
NULL );
m_dwLastOperationError = ::GetLastError();
hres = (m_DeviceDataHandle != INVALID_HANDLE_VALUE) ?
S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,m_dwLastOperationError);
return hres;
}
VOID
UsdSampDevice::
RunNotifications(VOID)
{
HANDLE hNotifyFileSystemChange = INVALID_HANDLE_VALUE;
DWORD dwErr;
CHAR szDirPath[MAX_PATH];
CHAR *pszLastSlash;
//
// Find name of the parent directory for out file and set up waiting on any
// changes in it.
//
StringCchCopyA(szDirPath, ARRAYSIZE(szDirPath), m_pszDeviceNameA);
pszLastSlash = strrchr(szDirPath,'\\');
if (pszLastSlash) {
*pszLastSlash = '\0';
}
hNotifyFileSystemChange = FindFirstChangeNotificationA(
szDirPath,
FALSE,
FILE_NOTIFY_CHANGE_SIZE |
FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME
);
if (hNotifyFileSystemChange == INVALID_HANDLE_VALUE) {
dwErr = ::GetLastError();
return;
}
// Set initial values for time and size
IsChangeDetected(NULL);
//
HANDLE hEvents[2] = {m_hShutdownEvent,hNotifyFileSystemChange};
BOOL fLooping = TRUE;
while (fLooping) {
dwErr = ::WaitForMultipleObjects(2,
hEvents,
FALSE,
INFINITE );
switch(dwErr) {
case WAIT_OBJECT_0+1:
// Change detected - signal
if (m_hSignalEvent !=INVALID_HANDLE_VALUE) {
// Which change ?
if (IsChangeDetected(&m_guidLastEvent)) {
m_pDcb->WriteToErrorLog(STI_TRACE_INFORMATION,
L"SampUSD::Monitored file change detected",
NOERROR) ;
::SetEvent(m_hSignalEvent);
}
}
// Go back to waiting for next file system event
FindNextChangeNotification(hNotifyFileSystemChange);
break;
case WAIT_OBJECT_0:
// Fall through
default:
fLooping = FALSE;
}
}
FindCloseChangeNotification(hNotifyFileSystemChange);
}
BOOL
UsdSampDevice::
IsChangeDetected(
GUID *pguidEvent,
BOOL fRefresh // TRUE
)
{
BOOL fRet = FALSE;
LARGE_INTEGER liNewHugeSize;
FILETIME ftLastWriteTime;
DWORD dwError;
WIN32_FILE_ATTRIBUTE_DATA sNewFileAttributes;
ZeroMemory(&sNewFileAttributes,sizeof(sNewFileAttributes));
dwError = NOERROR;
if ( GetFileAttributesExA(m_pszDeviceNameA,GetFileExInfoStandard, &sNewFileAttributes)) {
ftLastWriteTime =sNewFileAttributes.ftLastWriteTime;
liNewHugeSize.LowPart = sNewFileAttributes.nFileSizeLow;
liNewHugeSize.HighPart= sNewFileAttributes.nFileSizeHigh ;
}
else {
BY_HANDLE_FILE_INFORMATION sFileInfo;
if (GetFileInformationByHandle(m_DeviceDataHandle,&sFileInfo)) {
ftLastWriteTime =sFileInfo.ftLastWriteTime;
liNewHugeSize.LowPart = sFileInfo.nFileSizeLow;
liNewHugeSize.HighPart= sFileInfo.nFileSizeHigh ;
}
else {
dwError = ::GetLastError();
}
}
if (NOERROR == dwError ) {
//
// First check size, because it is easy to change time without changing size
//
if (m_dwLastHugeSize.QuadPart != liNewHugeSize.QuadPart) {
if (pguidEvent) {
*pguidEvent = guidEventSizeChanged;
}
fRet = TRUE;
}
else {
if (CompareFileTime(&m_ftLastWriteTime,&ftLastWriteTime) == -1 ) {
if (pguidEvent) {
*pguidEvent = guidEventTimeChanged;
}
fRet = TRUE;
}
else {
// Nothing really changed
}
}
m_ftLastWriteTime = ftLastWriteTime;
m_dwLastHugeSize = liNewHugeSize;
}
return fRet;
}
VOID
FileChangeThread(
LPVOID lpParameter
)
{
UsdSampDevice *pThisDevice = (UsdSampDevice *)lpParameter;
pThisDevice->RunNotifications();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -