2025-11-28 00:35:46 +09:00

206 lines
5.8 KiB
C++

//////////////////////////////////////////////////////////////////////////////
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include <wsdapi.h>
// FileService.h is automatically generated from FileService.idl
#include "FileService.h"
// Include FileServiceProxy for CFileServiceEventSource class
#include "FileServiceProxy.h"
WSD_LOCALIZED_STRING thisDeviceName = {NULL, L"File Service Device"};
WSD_LOCALIZED_STRING_LIST thisDeviceNameList = {NULL, &thisDeviceName};
// thisDeviceNameList is the FriendlyName
// "0.095" is the FirmwareVersion
// "0123456789-9876543210" is the SerialNumber
const WSD_THIS_DEVICE_METADATA thisDeviceMetadata = {
&thisDeviceNameList,
L"0.095",
L"0123456789-9876543210",
};
//////////////////////////////////////////////////////////////////////////////
// CFileServiceService Class
// Implements the service functionality
//////////////////////////////////////////////////////////////////////////////
class CFileServiceService : public IFileService
{
private:
ULONG m_cRef;
WCHAR m_szFileDirectory[MAX_PATH];
public:
CFileServiceService();
HRESULT Init(LPCWSTR pszFileDirectory);
HRESULT STDMETHODCALLTYPE GetFile(
GET_FILE_REQUEST* parameters,
GET_FILE_RESPONSE** parametersOut);
HRESULT STDMETHODCALLTYPE GetFileList(
GET_FILE_LIST_RESPONSE** parametersOut);
public:
//////////////////////////////////////////////////////////////////////////
// Methods to make this class act like a COM object
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject)
{
if (NULL == ppvObject)
{
return E_POINTER;
}
HRESULT hr = S_OK;
*ppvObject = NULL;
if (( __uuidof(IFileService) == riid) ||
( __uuidof(IUnknown) == riid) )
{
*ppvObject = (IFileService *)this;
}
else
{
hr = E_NOINTERFACE;
}
if (SUCCEEDED(hr))
{
((LPUNKNOWN) *ppvObject)->AddRef( );
}
return hr;
}
ULONG STDMETHODCALLTYPE AddRef()
{
ULONG ulNewRefCount = (ULONG)InterlockedIncrement((LONG *)&m_cRef);
return ulNewRefCount;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ulNewRefCount = (ULONG)InterlockedDecrement((LONG *)&m_cRef);
if( 0 == ulNewRefCount )
{
delete this;
}
return ulNewRefCount;
}
};
//////////////////////////////////////////////////////////////////////////////
// CFileChangeNotificationThread Class
// Performs worker thread that monitors the file system for changes
//////////////////////////////////////////////////////////////////////////////
class CFileChangeNotificationThread
{
private:
WCHAR m_szDirectory[MAX_PATH];
IWSDDeviceHost* m_pHost;
WCHAR m_szServiceId[MAX_PATH];
// Handle for the change notification thread
HANDLE m_hThread;
// Handle to signal shutdown of notification thread
HANDLE m_hWait;
CFileServiceEventSource* m_eventSource;
public:
CFileChangeNotificationThread();
~CFileChangeNotificationThread();
HRESULT Init(
LPCWSTR pszDirectory,
LPCWSTR pszServiceId,
IWSDDeviceHost* pHost);
// Starts the file change notification thread
HRESULT Start();
// Stops the file change notification thread
HRESULT Stop();
//////////////////////////////////////////////////////////////////////////
// WINAPI wrapper so we can call ThreadProc() in a thread callback
//////////////////////////////////////////////////////////////////////////
static DWORD WINAPI StaticThreadProc(
LPVOID pParams
)
{
if( NULL != pParams )
{
// Ignore result
(void)((CFileChangeNotificationThread*)pParams)->ThreadProc();
}
return 0;
}
private:
// Performs the file change notification work
HRESULT ThreadProc();
// Notifies the client via the FileChangeEvent
void NotifyClient(
LPCWSTR pszFileName,
DWORD dwAction);
};
//////////////////////////////////////////////////////////////////////////////
// CSendAttachmentThread Class
// Performs worker thread sends an attachment back to the client
//////////////////////////////////////////////////////////////////////////////
class CSendAttachmentThread
{
private:
WCHAR m_szFilePath[MAX_PATH];
IWSDOutboundAttachment* m_pAttachment;
public:
// ~CSendAttachmentThread is normally called only from ThreadProc(), but
// must be public so CSendAttachmentThread can be cleaned up if an
// initialization error occurs.
~CSendAttachmentThread();
CSendAttachmentThread();
HRESULT Init(
LPCWSTR pszFilePath,
IWSDOutboundAttachment* pAttachment);
// Starts the send-attachment thread via thread-pool thread
HRESULT Start();
//////////////////////////////////////////////////////////////////////////
// WINAPI wrapper so we can call ThreadProc() in a thread callback
//////////////////////////////////////////////////////////////////////////
static DWORD WINAPI StaticThreadProc(
LPVOID pParams)
{
if( NULL != pParams )
{
// Ignore result
(void)((CSendAttachmentThread*)pParams)->ThreadProc();
}
return 0;
}
private:
// ThreadProc - Performs the send attachment work
HRESULT ThreadProc();
};