📄 msmqdev.cxx
字号:
// @func BOOL | MMQ_IOControl | Device IO control routine
// @parm DWORD | dwOpenData | value returned from CON_Open call
// @parm DWORD | dwCode | io control code to be performed
// @parm PBYTE | pBufIn | input data to the device
// @parm DWORD | dwLenIn | number of bytes being passed in
// @parm PBYTE | pBufOut | output data from the device
// @parm DWORD | dwLenOut |maximum number of bytes to receive from device
// @parm PDWORD | pdwActualOut | actual number of bytes received from device
// @rdesc Returns TRUE for success, FALSE for failure
// @remark Routine exported by a device driver. "PRF" is the string passed
// in as lpszType in RegisterDevice
#ifdef _PREFAST_
#pragma prefast(disable:214,"BOOL + HRESULT are both currently 4 byte values on CE. All the return values cast around to them are safe.")
#endif
extern "C" BOOL MMQ_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
HRESULT hr;
if (dwCode == IOCTL_PSL_NOTIFY) {
DEVICE_PSL_NOTIFY pslPacket;
if ((pBufIn==NULL) || (0 == CeSafeCopyMemory(&pslPacket,pBufIn,sizeof(pslPacket)))) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if ((pslPacket.dwSize == sizeof(DEVICE_PSL_NOTIFY)) && (pslPacket.dwFlags == DLL_PROCESS_EXITING)){
SVSUTIL_ASSERT (*(HANDLE *)dwData == pslPacket.hProc);
scapi_ProcExit ((HANDLE)pslPacket.hProc);
}
return STATUS_SUCCESS;
}
if (dwData != TRUE) {
// Security note: We're safe dereferencing dwData because it can only be supplied
// by services.exe. No means for a calling app to modify this.
HANDLE *hCallerProc = (HANDLE *)dwData;
SVSUTIL_ASSERT (hCallerProc);
if (! *hCallerProc)
*hCallerProc = GetCallerProcess ();
SVSUTIL_ASSERT (*hCallerProc == GetCallerProcess());
}
switch (dwCode) {
case IOCTL_MSMQ_INVOKE:
{
// PSL marshaller logic. This is what processes calls from user mode
// apps like MQCreateQueue.
ce::psl_stub<> stub(pBufIn, dwLenIn);
switch(stub.function()) {
case MQAPI_CODE_MQCreateQueue:
hr = stub.call(scapi_MQCreateQueuePSL);
break;
case MQAPI_CODE_MQDeleteQueue:
hr = stub.call(scapi_MQDeleteQueuePSL);
break;
case MQAPI_CODE_MQGetQueueProperties:
hr = stub.call(scapi_MQGetQueuePropertiesPSL);
break;
case MQAPI_CODE_MQSetQueueProperties:
hr = stub.call(scapi_MQSetQueuePropertiesPSL);
break;
case MQAPI_CODE_MQOpenQueue:
hr = stub.call(scapi_MQOpenQueuePSL);
break;
case MQAPI_CODE_MQCloseQueue:
hr = stub.call(scapi_MQCloseQueuePSL);
break;
case MQAPI_CODE_MQCreateCursor:
hr = stub.call(scapi_MQCreateCursorPSL);
break;
case MQAPI_CODE_MQCloseCursor:
hr = stub.call(scapi_MQCloseCursorPSL);
break;
case MQAPI_CODE_MQHandleToFormatName:
hr = stub.call(scapi_MQHandleToFormatNamePSL);
break;
case MQAPI_CODE_MQPathNameToFormatName:
hr = stub.call(scapi_MQPathNameToFormatNamePSL);
break;
case MQAPI_CODE_MQSendMessage:
hr = stub.call(scapi_MQSendMessagePSL);
break;
case MQAPI_CODE_MQReceiveMessage:
hr = stub.call(scapi_MQReceiveMessagePSL);
break;
case MQAPI_CODE_MQFreeMemory:
hr = stub.call(scapi_MQFreeMemoryPSL);
break;
case MQAPI_CODE_MQGetMachineProperties:
hr = stub.call(scapi_MQGetMachinePropertiesPSL);
break;
case MQAPI_CODE_MQMgmtGetInfo2:
hr = stub.call(scmgmt_MQMgmtGetInfo2PSL);
break;
case MQAPI_CODE_MQMgmtAction:
hr = stub.call(scmgmt_MQMgmtActionPSL);
break;
default:
hr = STATUS_INTERNAL_ERROR;
break;
}
} // End case IOCTL_MSMQ_INVOKE
return svsutil_DWORDtoBOOLErrCode(hr);
break;
// Process HTTP request for MSMQ
case MQAPI_Code_SRMPControl: {
if (GetCallerVMProcessId() != GetCurrentProcessId()) {
// This call can only be made from the web server (in particular
// srmpIsapi.dll) running in servicesd.exe space into MSMQ.
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
}
if (!g_fHaveSRMP || !pBufIn || dwLenIn != sizeof(SrmpIOCTLPacket) || !pBufOut || dwLenOut != sizeof(DWORD)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
// Even though there are embedded pointers in this structure which we
// arguably should be marshalling, because only web server in servicesd.exe
// calls us (in same process space) don't bother.
SrmpAcceptHttpRequest((SrmpIOCTLPacket *) pBufIn,(DWORD*) pBufOut);
break;
}
//
// Services IOControl codes.
//
case IOCTL_SERVICE_START:
// only perform registry operations on SERVICE IOControls because other
// IOControls are called by existing MSMQ admin utilities which are responsible for setting.
SetRegistryStartup(1);
hr = scmgmt_MQMgmtAction (NULL, gs_MachineToken, MACHINE_ACTION_STARTUP);
break;
case IOCTL_SERVICE_STOP:
SetRegistryStartup(0);
hr = scmgmt_MQMgmtAction (NULL, gs_MachineToken, MACHINE_ACTION_SHUTDOWN);
break;
case IOCTL_SERVICE_CONSOLE:
hr = scmgmt_MQMgmtAction (NULL, gs_MachineToken, MACHINE_ACTION_CONSOLE);
break;
#if defined (SC_VERBOSE)
case IOCTL_SERVICE_DEBUG:
if ((dwLenIn == sizeof(L"console")) && (wcsicmp ((WCHAR *)pBufIn, L"console") == 0))
g_bOutputChannels = VERBOSE_OUTPUT_CONSOLE;
else if ((dwLenIn == sizeof(L"serial")) && (wcsicmp ((WCHAR *)pBufIn, L"serial") == 0))
g_bOutputChannels = VERBOSE_OUTPUT_DEBUGMSG;
else if ((dwLenIn == sizeof(L"file")) && (wcsicmp ((WCHAR *)pBufIn, L"file") == 0))
g_bOutputChannels = VERBOSE_OUTPUT_LOGFILE;
else if (dwLenIn == sizeof(DWORD))
g_bCurrentMask = *(unsigned int *)pBufIn;
else {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
hr = STATUS_SUCCESS;
break;
#endif
case IOCTL_SERVICE_STATUS:
__try {
if (!pBufOut || dwLenOut < sizeof(DWORD)) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
*(DWORD *)pBufOut = glServiceState;
if (pdwActualOut)
*pdwActualOut = sizeof(DWORD);
}
__except (ReportFault(GetExceptionInformation(),0), EXCEPTION_EXECUTE_HANDLER) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
break;
default:
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_FATAL, L"Unknown control code %d\n", dwCode);
#endif
hr = STATUS_INVALID_PARAMETER;
}
return svsutil_DWORDtoBOOLErrCode(hr);
}
#ifdef _PREFAST_
#pragma prefast(enable:214,"")
#endif
// @func void | MMQ_PowerUp | Device powerup routine
// @comm Called to restore device from suspend mode. You cannot call any
// routines aside from those in your dll in this call.
extern "C" void MMQ_PowerUp(void)
{
return;
}
// @func void | MMQ_PowerDown | Device powerdown routine
// @comm Called to suspend device. You cannot call any routines aside from
// those in your dll in this call.
extern "C" void MMQ_PowerDown(void)
{
return;
}
//
// These do nothing in DLL
//
void scce_Listen (void) {
}
HRESULT scce_Shutdown (void) {
return MQ_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -