📄 upnploader.cpp
字号:
goto Cleanup;
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
DeleteFileW(g_pszHTMLDeviceListPath); // the fail may not exist
fRet = MoveFileW(pszTmpPath,g_pszHTMLDeviceListPath);
Cleanup:
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
if (pszTmpPath)
delete [] pszTmpPath;
return fRet;
}
HostedDeviceInfo *
HostedDeviceInfo::FindRunningDevice(PCWSTR pszDeviceId)
{
LIST_ENTRY *pListEntry;
HostedDeviceInfo *pDev;
for (pListEntry = runningDeviceList.Flink; pListEntry != &runningDeviceList; pListEntry = pListEntry->Flink )
{
pDev = CONTAINING_RECORD(pListEntry,HostedDeviceInfo,link);
if (wcscmp(pszDeviceId, pDev->bstrDeviceId) == 0)
break;
}
return (pListEntry != &runningDeviceList ? pDev : NULL);
}
DWORD WINAPI
DeviceLoaderProc( PVOID)
{
HRESULT hr;
RegEntry upnpDevicesKey(UPNPDEVICESKEY);
HostedDeviceInfo::InitializeRunningDeviceList();
// Initialize COM
hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);
if (FAILED(hr))
{
TraceError("Cannot initialize COM\n", hr);
return hr;
}
// Create the UPnPRegistrar object
hr = CoCreateInstance(__uuidof(UPnPRegistrar),NULL,CLSCTX_INPROC_SERVER,__uuidof(IUPnPRegistrar), (LPVOID *)&g_upnpRegistrar);
if (FAILED(hr))
{
TraceError("Cannot instantiate UPnPRegistrar\n", hr);
goto Cleanup;
}
// Create the named event that will be used to signal us
g_hUPnPHostEvent = CreateEvent(NULL,FALSE,FALSE,UPNPLOADEREVENTNAME);
if (g_hUPnPHostEvent == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
{
TraceTag(ttidError,"DeviceLoaderProc: %s event creation error %d\n",UPNPLOADEREVENTNAME, GetLastError());
goto Cleanup;
}
while (TRUE)
{
DWORD dwWait;
// start registered devices
HostedDeviceInfo::UpdateRunningDeviceList();
// Wait on the named event for someone to signal us that a device has been registered or unregistered
TraceTag(ttidLoader, "DeviceLoaderProc: waiting for registration events ...\n");
dwWait = WaitForSingleObject(g_hUPnPHostEvent,INFINITE);
TraceTag(ttidLoader, "DeviceLoaderProc: wait returned %d\n", dwWait);
fShutdown = upnpDevicesKey.GetNumber(UPNPLOADERSIGNALVALUE,0);
if (dwWait != WAIT_OBJECT_0 || fShutdown)
{
TraceTag(ttidLoader, "DeviceLoaderProc: exiting\n");
break;
}
}
Cleanup:
upnpDevicesKey.DeleteValue(UPNPLOADERSIGNALVALUE); // signal is transient. Delete after reading
HostedDeviceInfo::CleanupRunningDeviceList();
if (g_hUPnPHostEvent)
{
CloseHandle(g_hUPnPHostEvent);
g_hUPnPHostEvent = NULL;
}
if (g_upnpRegistrar != NULL)
{
g_upnpRegistrar->Release();
g_upnpRegistrar = NULL;
}
CoUninitialize();
return (DWORD) hr;
}
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("UPNPLOADER"), {
TEXT("Misc"), TEXT("Loader"), TEXT(""), TEXT(""),
TEXT(""),TEXT(""),TEXT(""),TEXT(""),
TEXT(""),TEXT(""),TEXT(""),TEXT(""),
TEXT(""),TEXT(""),TEXT("Trace"),TEXT("Error") },
0x00008000
};
#endif
PWCHAR g_pszFile;
#ifdef UPNPLOADER_PROGRAM
// standalone program
void Usage()
{
printf("Usage: upnploader <options>\n"
"\t-b Debug Break\n"
"\t-c clean registry\n"
"\t-k kill previous instance\n"
);
exit(1);
}
void wmain(int argc, WCHAR *argv[])
{
int i;
BOOL bClean = FALSE;
BOOL bDebugBreak = FALSE;
BOOL bKill = FALSE;
// Process args
for (i=1;i<argc;i++) {
if ((argv[i][0] == TEXT('-')) || (argv[i][0] == TEXT('/'))) {
switch (argv[i][1]) {
#ifdef DEBUG
case TEXT('b'):
case TEXT('B'):
bDebugBreak = TRUE;
break;
#endif
case TEXT('c'):
case TEXT('C'):
bClean = TRUE; // clean all existing upnp device registry keys
break;
case TEXT('k'):
case TEXT('K'):
bKill = TRUE; // kill a previous instance of the device loader
break;
case TEXT('f'):
case TEXT('F'):
if (argv[i][2] == TEXT(':'))
g_pszFile = _wcsdup(argv[i]+3);
//else
// Usage();
break;
default:
Usage();
break;
}
}
}
#ifdef DEBUG
DEBUGREGISTER(NULL);
if (bDebugBreak)
DebugBreak();
#endif
if (bClean)
{ // delete all existing upnp device keys in the registry before we start
RegEntry upnpDevicesKey(UPNPDEVICESKEY,HKEY_LOCAL_MACHINE,FALSE);
RegEnumSubKeys enumDevices(&upnpDevicesKey);
while (enumDevices.Next() == 0)
{
TraceTag(ttidLoader,"Deleting key %ls\n",enumDevices.GetName());
RegDeleteKey(upnpDevicesKey.GetKey(),enumDevices.GetName());
}
}
if (bKill)
{
// kill a previous instance of this program by setting a special key in the registry
HANDLE hUPnPHostEvent = CreateEvent(NULL,FALSE,FALSE,UPNPLOADEREVENTNAME);
if (hUPnPHostEvent != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
{
RegEntry upnpDevicesKey(UPNPDEVICESKEY,HKEY_LOCAL_MACHINE);
upnpDevicesKey.SetValue(UPNPLOADERSIGNALVALUE, LOADER_SIGNAL_STOP );
SetEvent(hUPnPHostEvent);
CloseHandle(hUPnPHostEvent);
TraceTag(ttidLoader,"Setting event to kill previous instance\n");
}
else
TraceTag(ttidError,"Event open error: No previous instance? \n");
return;
}
DeviceLoaderProc();
}
#else
// DLL stream driver
extern "C" {
DWORD WINAPI UPL_Init(DWORD dwInfo );
BOOL WINAPI UPL_Deinit( DWORD dwData );
HANDLE WINAPI UPL_Open( DWORD dwData, DWORD dwAccessCode, DWORD dwShareMode);
BOOL WINAPI UPL_Close(DWORD dwOpenData);
DWORD WINAPI UPL_Read(DWORD dwOpenData, LPVOID pBuf, DWORD len);
DWORD WINAPI UPL_Write( DWORD dwOpenData, LPCVOID pBuf, DWORD len);
DWORD WINAPI UPL_Seek(DWORD dwOpenData, long pos, DWORD type);
void WINAPI UPL_PowerUp(DWORD dwData);
void WINAPI UPL_PowerDown( DWORD dwData);
BOOL WINAPI UPL_IOControl( DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,DWORD dwLenOut, PDWORD pdwActualOut);
};
HANDLE g_hUPnPLoaderThread;
DWORD Startup()
{
if(!g_hUPnPLoaderThread)
g_hUPnPLoaderThread = CreateThread(NULL, 0, DeviceLoaderProc, NULL, 0, NULL);
if(g_hUPnPLoaderThread)
{
g_fState = SERVICE_STATE_ON;
return TRUE;
}
else
return FALSE;
}
BOOL Shutdown()
{
if (g_hUPnPHostEvent && g_hUPnPLoaderThread)
{
// set a particular value in the registry to tell the DeviceLoaderProc thread to stop.
// Why not use a global variable ? Only because we want the code to build as a program or a DLL service.
RegEntry upnpDevicesKey(UPNPDEVICESKEY,HKEY_LOCAL_MACHINE);
upnpDevicesKey.SetValue(UPNPLOADERSIGNALVALUE, LOADER_SIGNAL_STOP );
SetEvent(g_hUPnPHostEvent);
WaitForSingleObject(g_hUPnPLoaderThread, INFINITE);
CloseHandle(g_hUPnPLoaderThread);
g_hUPnPLoaderThread = NULL;
}
g_fState = SERVICE_STATE_OFF;
return TRUE;
}
DWORD WINAPI
UPL_Init(
DWORD dwInfo
)
{
TraceTag(ttidInit, "UPL_Init called\n");
return Startup();
}
BOOL WINAPI
UPL_Deinit(
DWORD dwData
)
{
TraceTag(ttidInit, "UPL_Deinit called\n");
return Shutdown();
}
HANDLE WINAPI
UPL_Open(
DWORD dwData,
DWORD dwAccessCode,
DWORD dwShareMode
)
{
return (HANDLE) NULL;
}
BOOL WINAPI
UPL_Close(
DWORD dwOpenData
)
{
return FALSE;
}
DWORD WINAPI
UPL_Read(
DWORD dwOpenData,
LPVOID pBuf,
DWORD len
)
{
return (ULONG) -1;
}
DWORD WINAPI
UPL_Write(
DWORD dwOpenData,
LPCVOID pBuf,
DWORD len
)
{
return (ULONG) -1;
}
DWORD WINAPI
UPL_Seek(
DWORD dwOpenData,
long pos,
DWORD type
)
{
return (ULONG) -1;
}
void WINAPI
UPL_PowerUp(
DWORD dwData
)
{
}
void WINAPI
UPL_PowerDown(
DWORD dwData
)
{
}
BOOL WINAPI UPL_IOControl( DWORD dwOpenData, DWORD dwCode,
PBYTE pBufIn, DWORD dwLenIn,
PBYTE pBufOut,DWORD dwLenOut, PDWORD pdwActualOut)
{
switch (dwCode)
{
case IOCTL_SERVICE_START:
return Startup();
case IOCTL_SERVICE_STOP:
return Shutdown();
case IOCTL_SERVICE_STATUS:
__try
{
if (!pBufOut || dwLenOut < sizeof(DWORD))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
*(DWORD *)pBufOut = g_fState;
if (pdwActualOut)
*pdwActualOut = sizeof(DWORD);
return TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
return FALSE;
}
extern "C"
BOOL
WINAPI
DllMain(IN HANDLE DllHandle,
IN ULONG Reason,
IN PVOID Context OPTIONAL)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
// initialize debugging
DEBUGREGISTER((HMODULE)DllHandle);
if(!UpnpHeapCreate())
return FALSE;
// We don't need to receive thread attach and detach
// notifications, so disable them to help application
// performance.
DisableThreadLibraryCalls((HMODULE)DllHandle);
g_fState = SERVICE_STATE_UNINITIALIZED;
break;
case DLL_PROCESS_DETACH:
UpnpHeapDestroy();
break;
}
return TRUE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -