www.pudn.com > WINCEOS.zip > service.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "btagpriv.h"
CRITICAL_SECTION g_csLock;
DWORD g_dwState = SERVICE_STATE_UNINITIALIZED;
CAGService* g_pAG = NULL;
HINSTANCE g_hInstance;
extern "C" BOOL WINAPI DllMain( HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
if (DLL_PROCESS_ATTACH == fdwReason) {
DisableThreadLibraryCalls((HMODULE)hInstDll);
DEBUGREGISTER((HINSTANCE)hInstDll);
g_hInstance = (HINSTANCE)hInstDll;
InitializeCriticalSection(&g_csLock);
}
else if (DLL_PROCESS_DETACH == fdwReason) {
DeleteCriticalSection(&g_csLock);
}
return TRUE;
}
//
// The following BAG_xxxxx functions are called by services.exe to control this particular
// services dll.
//
extern "C" DWORD BAG_Init (DWORD dwData)
{
BOOL fRetVal = TRUE;
HKEY hk = NULL;
DWORD cdwBytes;
DWORD dwStartService = FALSE;
EnterCriticalSection(&g_csLock);
if (! g_pAG) {
DWORD dwErr;
g_pAG = new CAGService;
if (! g_pAG) {
fRetVal = FALSE;
SetLastError(ERROR_OUTOFMEMORY);
goto exit;
}
dwErr = g_pAG->Init();
if (ERROR_SUCCESS != dwErr) {
fRetVal = FALSE;
SetLastError(dwErr);
goto exit;
}
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_AG_SERVICE, 0, 0, &hk);
if (ERROR_SUCCESS != dwErr) {
fRetVal = FALSE;
SetLastError(dwErr);
goto exit;
}
cdwBytes = sizeof(dwStartService);
RegQueryValueEx(hk, _T("IsEnabled"), 0, NULL, (PBYTE)&dwStartService, &cdwBytes);
if (dwStartService) {
g_dwState = SERVICE_STATE_STARTING_UP;
dwErr = g_pAG->Start();
if (ERROR_SUCCESS != dwErr) {
fRetVal = FALSE;
SetLastError(dwErr);
goto exit;
}
g_dwState = SERVICE_STATE_ON;
}
}
else {
fRetVal = FALSE;
SetLastError(ERROR_ALREADY_INITIALIZED);
}
exit:
if ((FALSE == fRetVal) && g_pAG) {
g_pAG->Deinit();
delete g_pAG;
g_pAG = NULL;
g_dwState = SERVICE_STATE_UNINITIALIZED;
}
if (hk) {
RegCloseKey(hk);
}
LeaveCriticalSection(&g_csLock);
return fRetVal;
}
extern "C" BOOL BAG_Deinit(DWORD dwData)
{
g_dwState = SERVICE_STATE_SHUTTING_DOWN;
EnterCriticalSection(&g_csLock);
if (g_pAG) {
g_pAG->Stop();
g_dwState = SERVICE_STATE_UNLOADING;
g_pAG->Deinit();
delete g_pAG;
g_pAG = NULL;
}
g_dwState = SERVICE_STATE_UNINITIALIZED;
LeaveCriticalSection(&g_csLock);
return TRUE;
}
extern "C" DWORD BAG_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
return TRUE;
}
extern "C" BOOL BAG_Close (DWORD dwData)
{
return TRUE;
}
extern "C" DWORD BAG_Write (DWORD dwData, LPCVOID pInBuf, DWORD dwInLen)
{
return -1;
}
extern "C" DWORD BAG_Read (DWORD dwData, LPVOID pBuf, DWORD dwLen)
{
return -1;
}
extern "C" DWORD BAG_Seek (DWORD dwData, long pos, DWORD type)
{
return (DWORD)-1;
}
extern "C" void BAG_PowerUp(void)
{
return;
}
extern "C" void BAG_PowerDown(void)
{
return;
}
extern "C" BOOL BAG_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
DWORD dwErr;
HKEY hk;
DWORD dwRegData;
switch (dwCode) {
case IOCTL_SERVICE_START:
if (g_pAG) {
g_dwState = SERVICE_STATE_STARTING_UP;
EnterCriticalSection(&g_csLock);
dwErr = g_pAG->Start();
if (ERROR_SUCCESS != dwErr) {
LeaveCriticalSection(&g_csLock);
g_dwState = SERVICE_STATE_OFF;
SetLastError(dwErr);
return FALSE;
}
LeaveCriticalSection(&g_csLock);
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_AG_SERVICE, 0, 0, &hk);
if (ERROR_SUCCESS != dwErr) {
LeaveCriticalSection(&g_csLock);
g_dwState = SERVICE_STATE_OFF;
SetLastError(dwErr);
return FALSE;
}
dwRegData = 1;
RegSetValueEx(hk, _T("IsEnabled"), 0, REG_DWORD, (PBYTE)&dwRegData, sizeof(dwRegData));
RegCloseKey(hk);
g_dwState = SERVICE_STATE_ON;
return TRUE;
}
SetLastError(ERROR_NOT_READY);
return FALSE;
case IOCTL_SERVICE_REFRESH:
if (g_pAG) {
g_dwState = SERVICE_STATE_SHUTTING_DOWN;
EnterCriticalSection(&g_csLock);
g_pAG->Stop();
g_dwState = SERVICE_STATE_STARTING_UP;
dwErr = g_pAG->Start();
if (ERROR_SUCCESS != dwErr) {
LeaveCriticalSection(&g_csLock);
g_dwState = SERVICE_STATE_OFF;
SetLastError(dwErr);
return FALSE;
}
g_dwState = SERVICE_STATE_ON;
LeaveCriticalSection(&g_csLock);
return TRUE;
}
SetLastError(ERROR_NOT_READY);
return FALSE;
case IOCTL_SERVICE_STOP:
if (g_pAG) {
g_dwState = SERVICE_STATE_SHUTTING_DOWN;
EnterCriticalSection(&g_csLock);
g_pAG->Stop();
g_dwState = SERVICE_STATE_OFF;
LeaveCriticalSection(&g_csLock);
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_AG_SERVICE, 0, 0, &hk);
if (ERROR_SUCCESS != dwErr) {
LeaveCriticalSection(&g_csLock);
g_dwState = SERVICE_STATE_OFF;
SetLastError(dwErr);
return FALSE;
}
dwRegData = 0;
RegSetValueEx(hk, _T("IsEnabled"), 0, REG_DWORD, (PBYTE)&dwRegData, sizeof(dwRegData));
RegCloseKey(hk);
return TRUE;
}
SetLastError(ERROR_NOT_READY);
return FALSE;
case IOCTL_SERVICE_STATUS:
if (g_pAG && pBufOut && (dwLenOut == sizeof(DWORD))) {
*(DWORD *)pBufOut = g_dwState;
if (pdwActualOut)
*pdwActualOut = sizeof(DWORD);
return TRUE;
}
break;
case IOCTL_AG_OPEN_AUDIO:
dwErr = g_pAG->OpenAudio();
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
return TRUE;
case IOCTL_AG_CLOSE_AUDIO:
dwErr = g_pAG->CloseAudio();
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
return TRUE;
case IOCTL_AG_OPEN_CONTROL:
{
BOOL fFirstOnly = FALSE;
if (pBufIn && (dwLenIn >= sizeof(BOOL))) {
fFirstOnly = *(BOOL*)pBufIn;
}
dwErr = g_pAG->OpenControlConnection(fFirstOnly);
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
return TRUE;
}
case IOCTL_AG_CLOSE_CONTROL:
dwErr = g_pAG->CloseControlConnection();
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
return TRUE;
case IOCTL_AG_SET_SPEAKER_VOL:
if (pBufIn && (dwLenIn >= sizeof(USHORT))) {
dwErr = g_pAG->SetSpeakerVolume(*(PUSHORT)pBufIn);
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
return TRUE;
}
break;
case IOCTL_AG_SET_MIC_VOL:
if (pBufIn && (dwLenIn >= sizeof(USHORT))) {
dwErr = g_pAG->SetMicVolume(*(PUSHORT)pBufIn);
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
return TRUE;
}
break;
case IOCTL_AG_GET_SPEAKER_VOL:
if (pBufOut && (dwLenOut >= sizeof(USHORT))) {
dwErr = g_pAG->GetSpeakerVolume((PUSHORT)pBufOut);
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
dwLenOut = sizeof(USHORT);
return TRUE;
}
break;
case IOCTL_AG_GET_MIC_VOL:
if (pBufOut && (dwLenOut >= sizeof(USHORT))) {
dwErr = g_pAG->GetMicVolume((PUSHORT)pBufOut);
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
dwLenOut = sizeof(USHORT);
return TRUE;
}
break;
case IOCTL_AG_GET_POWER_MODE:
if (pBufOut && (dwLenOut >= sizeof(BOOL))) {
dwErr = g_pAG->GetPowerMode((BOOL*)pBufOut);
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
dwLenOut = sizeof(BOOL);
return TRUE;
}
break;
case IOCTL_AG_SET_POWER_MODE:
if (pBufIn && (dwLenIn >= sizeof(BOOL))) {
BOOL fMode = (*(PDWORD)pBufIn) ? TRUE : FALSE;
dwErr = g_pAG->SetPowerMode(fMode);
if (ERROR_SUCCESS != dwErr) {
SetLastError(dwErr);
return FALSE;
}
return TRUE;
}
break;
case IOCTL_SERVICE_DEREGISTER_SOCKADDR:
case IOCTL_SERVICE_DEBUG:
case IOCTL_SERVICE_STARTED:
case IOCTL_SERVICE_CONTROL:
return TRUE;
case IOCTL_SERVICE_CONNECTION:
case IOCTL_SERVICE_REGISTER_SOCKADDR:
return FALSE;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}