⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btsvc.cxx

📁 This a sample Bluetooth application which illustrates the use of Windows CE Bluetooth stack
💻 CXX
📖 第 1 页 / 共 2 页
字号:

			continue;
		}

		break;
	}

	BthSetSecurityUI (NULL, 0, 0);

	PostMessage (ghWndHidden, WM_USER + 2, 0, 0);

	delete gThreadPool;
	gThreadPool = NULL;

	if (WAIT_OBJECT_0 != WaitForSingleObject (hUIThread, BTH_SERVICE_TIMEOUT))
		TerminateThread (hUIThread, 0);

	CloseHandle (hUIThread);

	CloseHandle (hAuthReq);

	gfServiceState = SERVICE_STATE_OFF;

	return FALSE;
}

//  @func PVOID | HLO_Init | Service initialization routine
//  @parm DWORD | dwData | Info passed to RegisterDevice
//  @rdesc      Returns a DWORD which will be passed to Open & Deinit or NULL if
//              unable to initialize the device.
//
//  This is called only once. Do the startup initialization in a thread
//  spawned by this function, but DO NOT BLOCK HERE!
//        
extern "C" DWORD BTS_Init (DWORD dwData)
{
#if ! defined (SDK_BUILD)
	HANDLE hEvent = OpenEvent (EVENT_ALL_ACCESS, FALSE, L"system/events/bluetooth/btsvc/firstboot");
	if (hEvent) 
		CloseHandle (hEvent);
	else {
		// intentionally link handle - one event per boot. This is only run once.
		CreateEvent (NULL, FALSE, FALSE, L"system/events/bluetooth/btsvc/firstboot");
	}
#endif

	ghServiceExitEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
	if (! ghServiceExitEvent)
		return FALSE;

	ghServiceThread = CreateThread (NULL, 0, BthServiceThread, NULL, 0, NULL);
	if (! ghServiceThread) {
		CloseHandle (ghServiceExitEvent);
		return FALSE;
	}

    return TRUE;
}

//  @func PVOID | HLO_Deinit | Device deinitialization routine
//  @parm DWORD | dwData | value returned from HLO_Init call
//  @rdesc	Returns TRUE for success, FALSE for failure.
//
//  The library WILL BE UNLOADED after this. Block here
//  until the state is completely clear and all the
//  threads are gone.
//
extern "C" BOOL BTS_Deinit(DWORD dwData)
{
	if (ghServiceExitEvent) {
		SetEvent (ghServiceExitEvent);
		CloseHandle (ghServiceExitEvent);
		ghServiceExitEvent = NULL;
	}

	if (ghServiceThread) {
		if (WAIT_OBJECT_0 != WaitForSingleObject (ghServiceThread, BTH_SERVICE_TIMEOUT))
			TerminateThread (ghServiceThread, 0);
		CloseHandle (ghServiceThread);
		ghServiceThread = NULL;
	}

    return TRUE;
}

//  @func PVOID | HLO_Open     | Device open routine
//  @parm DWORD | dwData       | value returned from HLO_Init call
//  @parm DWORD | dwAccess     | requested access (combination of GENERIC_READ
//                               and GENERIC_WRITE)
//  @parm DWORD | dwShareMode | requested share mode (combination of
//                               FILE_SHARE_READ and FILE_SHARE_WRITE)
//  @rdesc	Returns a DWORD which will be passed to Read, Write, etc or NULL if
//                               unable to open device.
//
//  We don't do anything here, but in a real service this is a place to create
//  client process state. HCO_Close will be called with this handle when the process
//  exits or terminates, so the clean-up is easy.
//
extern "C" DWORD BTS_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
    return TRUE;
}

//  @func BOOL  | HLO_Close | Device close routine
//  @parm DWORD | dwOpenData | value returned from HLO_Open call
//  @rdesc      Returns TRUE for success, FALSE for failure
//
//  Clean-up the client process state here.
//
extern "C" BOOL BTS_Close (DWORD dwData) 
{
    return TRUE;
}

//  @func DWORD   | HLO_Write  | Device write routine
//  @parm DWORD   | dwOpenData | value returned from HLO_Open call
//  @parm LPCVOID | pBuf     | buffer containing data
//  @parm DWORD   | len        | maximum length to write [IN BYTES, NOT WORDS!!!]
//  @rdesc           Returns -1 for error, otherwise the number of bytes written.  The
//                   length returned is guaranteed to be the length requested unless an
//                   error condition occurs.
//
//  This is a vestige of streaming driver interface. We don't use it for services.
//
extern "C" DWORD BTS_Write (DWORD dwData, LPCVOID pInBuf, DWORD dwInLen)
{
    return -1;
}

//  @func DWORD  | HLO_Read   | Device read routine
//  @parm DWORD  | dwOpenData | value returned from HLO_Open call
//  @parm LPVOID | pBuf       | buffer to receive data
//  @parm DWORD  | len        | maximum length to read [IN BYTES, not WORDS!!]
//  @rdesc      Returns 0 for end of file, -1 for error, otherwise the number of
//              bytes read.  The length returned is guaranteed to be the length
//              requested unless end of file or an error condition occurs.
//
//  This is a vestige of streaming driver interface. We don't use it for services.
//
extern "C" DWORD BTS_Read (DWORD dwData, LPVOID pBuf, DWORD dwLen)
{
    return -1;
}

//  @func DWORD | HLO_Seek   | Device seek routine
//  @parm DWORD | dwOpenData | value returned from HLO_Open call
//  @parm long  | pos        | position to seek to (relative to type)
//  @parm DWORD | type       | FILE_BEGIN, FILE_CURRENT, or FILE_END
//  @rdesc      Returns current position relative to start of file, or -1 on error
//
//  This is a vestige of streaming driver interface. We don't use it for services.
//
extern "C" DWORD BTS_Seek (DWORD dwData, long pos, DWORD type)
{
    return (DWORD)-1;
}

//  @func void | HLO_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.
//
//  This is a vestige of streaming driver interface. We don't use it for services.
//
extern "C" void BTS_PowerUp(void)
{
	return;
}

//  @func void | HLO_PowerDown | Device powerdown routine
//  @comm      Called to suspend device.  You cannot call any routines aside from
//             those in your dll in this call.
//
//  This is a vestige of streaming driver interface. We don't use it for services.
//
extern "C" void BTS_PowerDown(void)
{
    return;
}

//  @func BOOL   | HLO_IOControl | Device IO control routine
//  @parm DWORD  | dwOpenData | value returned from HLO_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
//
//  This is THE way to expose both manageability of the service and the feature API set.
//  Consumer of the API set will marshal input arguments into input buffer (pBufIn).
//  This function unmarshals it and executes the API, and then marshals output parameters
//  into output buffer (pBufOut).
//
extern "C" BOOL BTS_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
			  DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
			  PDWORD pdwActualOut)
{
    switch (dwCode) {
        // Control code sent to start a service (not the same as IOCTL_SERVICE_STARTED).
        case IOCTL_SERVICE_START: // start a service that is currently in the stopped stage.
			if (gfServiceState == SERVICE_STATE_OFF) {
				if (ghServiceThread) {
					if (WAIT_TIMEOUT == WaitForSingleObject (ghServiceThread, BTH_SERVICE_TIMEOUT))
						return FALSE;

					CloseHandle (ghServiceThread);
					ghServiceThread = NULL;
				}

				ResetEvent (ghServiceExitEvent);
				ghServiceThread = CreateThread (NULL, 0, BthServiceThread, NULL, 0, NULL);
				return ghServiceThread != NULL;
			}

			SetLastError (ERROR_SERVICE_ALREADY_RUNNING);
			return FALSE;

                // stop a service and for refresh bring it up again.
                // REFRESH is required for more complicated servers
                // that only read in their registry configuration
                // during initilization.

        case IOCTL_SERVICE_REFRESH:
        case IOCTL_SERVICE_STOP:
			if (gfServiceState == SERVICE_STATE_ON) {
				if (ghServiceThread) {
					SetEvent (ghServiceExitEvent);
					if (WAIT_TIMEOUT == WaitForSingleObject (ghServiceThread, BTH_SERVICE_TIMEOUT))
						return FALSE;

					CloseHandle (ghServiceThread);
					ghServiceThread = NULL;
				}

				if (dwCode == IOCTL_SERVICE_REFRESH) {
					ResetEvent (ghServiceExitEvent);
					ghServiceThread = CreateThread (NULL, 0, BthServiceThread, NULL, 0, NULL);
					return ghServiceThread != NULL;
				}

				return TRUE;
			}

			SetLastError (ERROR_SERVICE_NOT_ACTIVE);
			return FALSE;


        case IOCTL_SERVICE_STATUS:
            if (pBufOut && dwLenOut == sizeof(DWORD))  {
                *(DWORD *)pBufOut = gfServiceState;
                if (pdwActualOut)
                    *pdwActualOut = sizeof(DWORD);
                return TRUE;
            }
            break;

                // IOCTL_SERVICE_CONTROL contains service specific information passed to it by
                // a calling application.
        case IOCTL_SERVICE_CONTROL:
            return TRUE;

                // Called once all initialization has completed and the session is ready
                // to start running.  By convention all services will (or at least should) be
                // passed their service handle (what RegisterService() returns).  This value
                // can be saved in case a service wishes to call DeregisterService on itself.
                //
                // This is not available in device.exe!
                //
        case IOCTL_SERVICE_STARTED:
            return TRUE;

        case IOCTL_SERVICE_REGISTER_SOCKADDR:
                // The super services thread or an application will call this IOCTL will
                // pBufIn = NULL as a means of querying whether or not the particular service
                // will support having a socket bound to it or not.  Service will return FALSE
                // if it was not designed to take IOCTL_SERVICE_CONNECTION commands, or
                // if it is not ready.
                //
                // This is not available in device.exe!
                //
            return FALSE;

        case IOCTL_SERVICE_DEREGISTER_SOCKADDR:
                // When our sockets are being disconnected this message is sent to us.
                //
                // This is not available in device.exe!
                //
            return TRUE;

        case IOCTL_SERVICE_CONNECTION:
                // This IOControl is called when a socket connection for a socked associated
				// with the service comes off the wire.  The socket accept() returns is the
                // value passed.  Note that it is the service's responsibilty to close
                // the socket, even if the service is not in the active state.
                //
                // This is not available in device.exe!
                //
            return FALSE;

                // This can be used to programmatically turn on/off debug zones.
        case IOCTL_SERVICE_DEBUG:
            return TRUE;

//		Unsupported SERVICES IOCTLs
//		case IOCTL_SERVICE_INSTALL:
//		case IOCTL_SERVICE_UNINSTALL:
    }

    SetLastError(ERROR_INVALID_PARAMETER);
    return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -