November 2001/Implementing Wireless Print for WinNT/Win2K
Listing 1: wlsmon.c
The implementation of the WLSMON API
/*------------------------------------------------------------------
WlsMon.c: Implementation of Wireless Print Monitor
Author: Zuoliu Ding
------------------------------------------------------------------*/
#include <windows.h>
#include <winspool.h>
#include <winsplp.h>
#include <wchar.h>
#include <regstr.h>
#include "wlsmon.h"
#define WLS_REG REGSTR_PATH_MONITORS L"\\Wireless Port\\Ports"
#define WLS L"WLS"
HANDLE hInst;
PINIPORT pIniFirstPort;
CRITICAL_SECTION SpoolerSection;
static HKEY hHKLM = HKEY_LOCAL_MACHINE;
static HKEY hKey;
static LONG lRet;
BOOL DllEntryPoint(HANDLE hModule, DWORD dwReason, LPVOID lpRes)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
hInst = hModule;
InitializeCriticalSection(&SpoolerSection);
DisableThreadLibraryCalls(hModule);
return TRUE;
}
case DLL_PROCESS_DETACH:
return TRUE;
}
UNREFERENCED_PARAMETER( lpRes );
}
MONITOREX MonitorEx = {
sizeof(MONITOR),
{
EnumPorts,
OpenPort,
NULL, // OpenPortEx is not supported
StartDocPort,
WritePort,
ReadPort,
EndDocPort,
ClosePort,
AddPort,
NULL, // AddPortEx is not supported
ConfigurePort,
DeletePort,
NULL, // GetPrinterDataFromPort is not supported
SetPortTimeOuts
}
};
LPMONITOREX InitializePrintMonitor(LPWSTR pRegistryRoot)
{
DWORD dwLen, dwIdx=0;
WCHAR wsz[80];
DWORD dwDisposition;
EnterSplSem();
lRet = RegCreateKeyEx(hHKLM, WLS_REG, 0, NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ, NULL, &hKey, &dwDisposition);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RCP:RegCreateKeyEx"))
return FALSE;
while (TRUE)
{
dwLen =80;
lRet = RegEnumValue(hKey, dwIdx, wsz, &dwLen,
NULL, NULL, NULL, NULL);
if (lRet==ERROR_NO_MORE_ITEMS || lRet!=ERROR_SUCCESS) break;
dwIdx++;
CreatePortEntry(wsz);
}
lRet = RegCloseKey(hKey); // handle of key to close
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"IPM:RegCloseKey"))
return FALSE;
LeaveSplSem();
return &MonitorEx;
}
BOOL StartDocPort(HANDLE hPort, LPWSTR pPrinterName, DWORD JobId,
DWORD Level, LPBYTE pDocInfo)
{
PINIPORT pIniPort = (PINIPORT)hPort;
if (pIniPort->Status & PP_STARTDOC) return TRUE;
pIniPort->pPrinterName = AllocSplStr(pPrinterName);
if (IsError(NULL, !pIniPort->pPrinterName, L"SDP:No Printer"))
return FALSE;
if (IsError(NULL,
!IsWLSPort(pIniPort->pName), L"SDP:Not WLSPort"))
return FALSE;
pIniPort->hPrinter = WlsConnectPrinter(pIniPort->pName, JobId);
if (IsError(NULL, !pIniPort->hPrinter, L"SDP:No Printer Hnd"))
return FALSE;
pIniPort->JobId = JobId;
pIniPort->Status |= PP_STARTDOC;
return TRUE;
}
BOOL WritePort(HANDLE hPort, LPBYTE pBuffer,
DWORD cbBuf, LPDWORD pcbWritten)
{
PINIPORT pIniPort = (PINIPORT)hPort;
if (IsError(NULL, !pIniPort->hPrinter, L"WP:No Printer Handle"))
return FALSE;
lRet = (LONG)WlsWritePrinter(pIniPort->hPrinter,
pBuffer, cbBuf, pcbWritten);
if (!lRet) EndDocPort(hPort);
return (BOOL)lRet;
}
BOOL EndDocPort(HANDLE hPort)
{
PINIPORT pIniPort = (PINIPORT)hPort;
HANDLE hPrinter;
if (!(pIniPort->Status & PP_STARTDOC)) return TRUE;
if (IsError(NULL, !pIniPort->hPrinter, L"EDP:No Printer Hnd"))
return FALSE;
WlsDisconnectPrinter(pIniPort->hPrinter);
if (OpenPrinter(pIniPort->pPrinterName, &hPrinter, NULL))
{
if (hPrinter)
{
SetJob(hPrinter, pIniPort->JobId,
0, NULL, JOB_CONTROL_SENT_TO_PRINTER);
ClosePrinter(hPrinter);
}
}
FreeSplStr(pIniPort->pPrinterName);
pIniPort->Status &= ~PP_STARTDOC;
return TRUE;
}
BOOL OpenPort(LPWSTR pName, PHANDLE pHandle)
{
EnterSplSem();
*pHandle = FindIniKey((PINIENTRY)pIniFirstPort, pName);
LeaveSplSem();
return TRUE;
}
BOOL ClosePort(HANDLE hPort)
{
PINIPORT pIniPort = (PINIPORT)hPort;
if (!pIniPort) return FALSE;
EnterSplSem();
DeletePortNode(pIniPort);
LeaveSplSem();
return TRUE;
}
BOOL ReadPort(HANDLE, LPBYTE pBuffer, DWORD cbBuf, LPDWORD pcbRead)
{
return TRUE;
}
BOOL SetPortTimeOuts(HANDLE, LPCOMMTIMEOUTS lpCTO, DWORD reserved)
{
return FALSE;
}
BOOL RegWritePort(LPWSTR pPortName, LPWSTR pVal)
{
WCHAR wsz[80];
lRet = RegOpenKeyEx(hHKLM, WLS_REG, 0, KEY_WRITE, &hKey);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RWP:RegOpenKeyEx"))
return FALSE;
lRet = RegSetValueEx(hKey, pPortName, 0, REG_SZ,
(LPBYTE)pVal, sizeof(WCHAR)*wcslen(pVal));
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RWP:RegSetValueEx"))
return FALSE;
lRet = RegCloseKey(hKey);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RWP:RegCloseKey"))
return FALSE;
return TRUE;
}
BOOL RegReadPort(LPWSTR pPortName, LPWSTR pVal)
{
DWORD dwLen=80, dwType=REG_SZ;
lRet = RegOpenKeyEx(hHKLM, WLS_REG, 0, KEY_READ, &hKey);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RRP:RegOpenKeyEx"))
return FALSE;
lRet =RegQueryValueEx(hKey, pPortName, 0, &dwType,
(LPBYTE)pVal, &dwLen);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RRP:RegQueryValueEx"))
return FALSE;
lRet = RegCloseKey(hKey);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RRP:RegCloseKey"))
return FALSE;
return TRUE;
}
BOOL RegDeletePort(LPWSTR pPortName)
{
lRet = RegOpenKeyEx(hHKLM, WLS_REG, 0, KEY_WRITE, &hKey);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RDP:RegOpenKeyEx"))
return FALSE;
lRet = RegDeleteValue(hKey, pPortName);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RDP:RegDeleteValue"))
return FALSE;
lRet = RegCloseKey(hKey);
if (IsError(NULL, lRet!=ERROR_SUCCESS, L"RDP:RegCloseKey"))
return FALSE;
return TRUE;
}
WORD RegGetPortData(LPWSTR pszVal)
{
LPWSTR pTmo = wcsstr(pszVal, L"::");
if (!pTmo) return 0;
*pTmo++ =0;
*pTmo++ =0;
return (WORD)wcstoul(pTmo, NULL, 10);
}
BOOL IsWLSPort(LPWSTR pPort)
{
if (_wcsnicmp(pPort, WLS, 3)) return FALSE;
return pPort[wcslen(pPort) -1] == L':';
}
BOOL IsError(HWND hWnd, BOOL bErr, LPWSTR wsMsg)
{
if (bErr) MessageBox(hWnd, wsMsg, L"WLS Monitor Error", MB_OK);
return bErr;
}
/* End of File */