ReactOS 0.4.15-dev-7788-g1ad9096
main.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Local Port Monitor
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Main functions
5 * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
6 */
7
8#include "precomp.h"
9
10// Global Variables
15
16// Local Constants
18 sizeof(MONITOR2), // cbSize
19 LocalmonEnumPorts, // pfnEnumPorts
20 LocalmonOpenPort, // pfnOpenPort
21 NULL, // pfnOpenPortEx
22 LocalmonStartDocPort, // pfnStartDocPort
23 LocalmonWritePort, // pfnWritePort
24 LocalmonReadPort, // pfnReadPort
25 LocalmonEndDocPort, // pfnEndDocPort
26 LocalmonClosePort, // pfnClosePort
27 LocalmonAddPort, // pfnAddPort moved to localui.dll since w2k, but~
28 LocalmonAddPortEx, // pfnAddPortEx
29 LocalmonConfigurePort, // pfnConfigurePort moved to localui.dll since w2k, but~
30 LocalmonDeletePort, // pfnDeletePort moved to localui.dll since w2k, but~
31 LocalmonGetPrinterDataFromPort, // pfnGetPrinterDataFromPort
32 LocalmonSetPortTimeOuts, // pfnSetPortTimeOuts
33 LocalmonXcvOpenPort, // pfnXcvOpenPort
34 LocalmonXcvDataPort, // pfnXcvDataPort
35 LocalmonXcvClosePort, // pfnXcvClosePort
36 LocalmonShutdown, // pfnShutdown
37 NULL, // pfnSendRecvBidiDataFromPort
38};
39
40
55static __inline BOOL
56_IsNEPort(PCWSTR pwszPortName)
57{
58 PCWSTR p = pwszPortName;
59
60 // First character needs to be 'N' (uppercase or lowercase)
61 if (*p != L'N' && *p != L'n')
62 return FALSE;
63
64 // Next character needs to be 'E' (uppercase or lowercase)
65 p++;
66 if (*p != L'E' && *p != L'e')
67 return FALSE;
68
69 // An optional hyphen may follow now.
70 p++;
71 if (*p == L'-')
72 p++;
73
74 // Now an arbitrary number of digits may follow.
75 while (*p >= L'0' && *p <= L'9')
76 p++;
77
78 // Finally, the virtual Ne port must be terminated by a colon.
79 if (*p != ':')
80 return FALSE;
81
82 // If this is the end of the string, we have a virtual Ne port.
83 p++;
84 return (*p == L'\0');
85}
86
87static void
89{
92
94 cbLocalPort = (wcslen(pwszLocalPort) + 1) * sizeof(WCHAR);
95}
96
99{
100 switch (fdwReason)
101 {
104 _LoadResources(hinstDLL);
105 break;
106 }
107
108 return TRUE;
109}
110
111void WINAPI
113{
114 PLOCALMON_HANDLE pLocalmon;
115 PLOCALMON_PORT pPort;
116 PLOCALMON_XCV pXcv;
118
119 TRACE("LocalmonShutdown(%p)\n", hMonitor);
120
121 pLocalmon = (PLOCALMON_HANDLE)hMonitor;
122
123 if ( pLocalmon->Sig != SIGLCMMON )
124 {
125 ERR("LocalmonShutdown : Invalid Monitor Handle\n",hMonitor);
126 return;
127 }
128
129 // Close all virtual file ports.
130 if (!IsListEmpty(&pLocalmon->FilePorts))
131 {
132 for (pEntry = pLocalmon->FilePorts.Flink; pEntry != &pLocalmon->FilePorts; pEntry = pEntry->Flink)
133 {
134 pPort = CONTAINING_RECORD(&pLocalmon->FilePorts.Flink, LOCALMON_PORT, Entry);
136 }
137 }
138
139 // Do the same for the open Xcv ports.
140 if (!IsListEmpty(&pLocalmon->XcvHandles))
141 {
142 for (pEntry = pLocalmon->XcvHandles.Flink; pEntry != &pLocalmon->XcvHandles; pEntry = pEntry->Flink)
143 {
146 }
147 }
148
149 // Now close all registry ports, remove them from the list and free their memory.
150 if (!IsListEmpty(&pLocalmon->RegistryPorts))
151 {
152 for (pEntry = pLocalmon->RegistryPorts.Flink; pEntry != &pLocalmon->RegistryPorts; pEntry = pEntry->Flink)
153 {
155 if ( LocalmonClosePort((HANDLE)pPort) ) continue;
156 RemoveEntryList(&pPort->Entry);
157 DllFreeSplMem(pPort);
158 }
159 }
160
161 // Finally clean the LOCALMON_HANDLE structure itself.
162 DeleteCriticalSection(&pLocalmon->Section);
163 DllFreeSplMem(pLocalmon);
164}
165
168{
169 DWORD cchMaxPortName;
170 DWORD cchPortName;
171 DWORD dwErrorCode;
172 DWORD dwPortCount;
173 DWORD i;
174 HKEY hKey;
175 PMONITOR2 pReturnValue = NULL;
176 PLOCALMON_HANDLE pLocalmon;
177 PLOCALMON_PORT pPort = NULL;
178
179 TRACE("InitializePrintMonitor2(%p, %p)\n", pMonitorInit, phMonitor);
180
181 // Create a new LOCALMON_HANDLE structure.
182 pLocalmon = DllAllocSplMem(sizeof(LOCALMON_HANDLE));
183 pLocalmon->Sig = SIGLCMMON;
185 InitializeListHead(&pLocalmon->FilePorts);
187 InitializeListHead(&pLocalmon->XcvHandles);
188
189 // The Local Spooler Port Monitor doesn't need to care about the given registry key and functions.
190 // Instead it uses a well-known registry key for getting its information about local ports. Open this one.
191 dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports", 0, KEY_READ, &hKey);
192 if (dwErrorCode != ERROR_SUCCESS)
193 {
194 ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
195 goto Cleanup;
196 }
197
198 // Get the number of ports and the length of the largest port name.
199 dwErrorCode = (DWORD)RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwPortCount, &cchMaxPortName, NULL, NULL, NULL);
200 if (dwErrorCode != ERROR_SUCCESS)
201 {
202 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
203 goto Cleanup;
204 }
205
206 // Loop through all ports.
207 for (i = 0; i < dwPortCount; i++)
208 {
209 // Allocate memory for a new LOCALMON_PORT structure and its name.
210 pPort = DllAllocSplMem(sizeof(LOCALMON_PORT) + (cchMaxPortName + 1) * sizeof(WCHAR));
211 if (!pPort)
212 {
213 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
214 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
215 goto Cleanup;
216 }
217
218 pPort->Sig = SIGLCMPORT;
219 pPort->pLocalmon = pLocalmon;
221 pPort->pwszPortName = (PWSTR)(pPort+1);
222
223 // Get the port name.
224 cchPortName = cchMaxPortName + 1;
225 dwErrorCode = (DWORD)RegEnumValueW(hKey, i, pPort->pwszPortName, &cchPortName, NULL, NULL, NULL, NULL);
226 if (dwErrorCode != ERROR_SUCCESS)
227 {
228 ERR("RegEnumValueW failed with status %lu!\n", dwErrorCode);
229 goto Cleanup;
230 }
231
232 // pwszPortName can be one of the following to be valid for this Port Monitor:
233 // COMx: - Physical COM port
234 // LPTx: - Physical LPT port (or redirected one using "net use LPT1 ...")
235 // FILE: - Opens a prompt that asks for an output filename
236 // C:\bla.txt - Redirection into the file "C:\bla.txt"
237 // \\COMPUTERNAME\PrinterName - Redirection to a shared network printer installed as a local port
238 //
239 // We can't detect valid and invalid ones by the name, so we can only exclude empty ports and the virtual "Ne00:", "Ne01:", ... ports.
240 // Skip the invalid ones here.
241 if (!cchPortName || _IsNEPort(pPort->pwszPortName))
242 {
243 DllFreeSplMem(pPort);
244 pPort = NULL;
245 continue;
246 }
247
248 // Add it to the list.
249 InsertTailList(&pLocalmon->RegistryPorts, &pPort->Entry);
250 TRACE("InitializePrintMonitor2 Port : %s \n",debugstr_w(pPort->pwszPortName));
251
252 // Don't let the cleanup routine free this.
253 pPort = NULL;
254 }
255
256 // Return our handle and the Print Monitor functions.
257 *phMonitor = (HANDLE)pLocalmon;
258 pReturnValue = &_MonitorFunctions;
259 dwErrorCode = ERROR_SUCCESS;
260
261Cleanup:
262 if (pPort)
263 DllFreeSplMem(pPort);
264
265 SetLastError(dwErrorCode);
266 return pReturnValue;
267}
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
Definition: main.c:26
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2859
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3691
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
static const WCHAR Cleanup[]
Definition: register.c:80
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define debugstr_w
Definition: kernel32.h:32
static IN DWORD IN LPVOID lpvReserved
#define KEY_READ
Definition: nt_native.h:1023
#define DWORD
Definition: nt_native.h:44
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
struct _MONITOR2 MONITOR2
#define TRACE(s)
Definition: solgame.cpp:4
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY XcvHandles
Definition: precomp.h:44
CRITICAL_SECTION Section
Definition: precomp.h:40
LIST_ENTRY FilePorts
Definition: precomp.h:42
LIST_ENTRY RegistryPorts
Definition: precomp.h:43
PWSTR pwszPortName
Definition: precomp.h:55
DWORD Sig
Definition: precomp.h:57
PLOCALMON_HANDLE pLocalmon
Definition: precomp.h:56
LIST_ENTRY Entry
Definition: precomp.h:54
HANDLE hFile
Definition: precomp.h:67
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
PVOID HANDLE
Definition: typedefs.h:73
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
static __inline BOOL _IsNEPort(PCWSTR pwszPortName)
Definition: main.c:56
void WINAPI LocalmonShutdown(HANDLE hMonitor)
Definition: main.c:112
static MONITOR2 _MonitorFunctions
Definition: main.c:17
PCWSTR pwszLocalMonitor
Definition: main.c:13
PMONITOR2 WINAPI InitializePrintMonitor2(PMONITORINIT pMonitorInit, PHANDLE phMonitor)
Definition: main.c:167
static void _LoadResources(HINSTANCE hinstDLL)
Definition: main.c:88
DWORD cbLocalMonitor
Definition: main.c:11
DWORD cbLocalPort
Definition: main.c:12
PCWSTR pwszLocalPort
Definition: main.c:14
BOOL WINAPI LocalmonStartDocPort(HANDLE hPort, PWSTR pPrinterName, DWORD JobId, DWORD Level, PBYTE pDocInfo)
Definition: ports.c:896
BOOL WINAPI LocalmonDeletePort(HANDLE hMonitor, LPWSTR pName, HWND hWnd, LPWSTR pPortName)
Definition: ports.c:1197
BOOL WINAPI LocalmonAddPortEx(HANDLE hMonitor, LPWSTR pName, DWORD Level, LPBYTE lpBuffer, LPWSTR lpMonitorName)
Definition: ports.c:1054
BOOL WINAPI LocalmonOpenPort(HANDLE hMonitor, PWSTR pName, PHANDLE pHandle)
Definition: ports.c:684
BOOL WINAPI LocalmonAddPort(HANDLE hMonitor, LPWSTR pName, HWND hWnd, LPWSTR pMonitorName)
Definition: ports.c:1137
BOOL WINAPI LocalmonWritePort(HANDLE hPort, PBYTE pBuffer, DWORD cbBuf, PDWORD pcbWritten)
Definition: ports.c:996
BOOL WINAPI LocalmonEnumPorts(HANDLE hMonitor, PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: ports.c:530
BOOL WINAPI LocalmonReadPort(HANDLE hPort, PBYTE pBuffer, DWORD cbBuffer, PDWORD pcbRead)
Definition: ports.c:843
BOOL WINAPI LocalmonGetPrinterDataFromPort(HANDLE hPort, DWORD ControlID, PWSTR pValueName, PWSTR lpInBuffer, DWORD cbInBuffer, PWSTR lpOutBuffer, DWORD cbOutBuffer, PDWORD lpcbReturned)
Definition: ports.c:630
BOOL WINAPI LocalmonEndDocPort(HANDLE hPort)
Definition: ports.c:493
BOOL WINAPI LocalmonConfigurePort(HANDLE hMonitor, LPWSTR pName, HWND hWnd, LPWSTR pPortName)
Definition: ports.c:1189
BOOL WINAPI LocalmonClosePort(HANDLE hPort)
Definition: ports.c:456
BOOL WINAPI LocalmonSetPortTimeOuts(HANDLE hPort, LPCOMMTIMEOUTS lpCTO, DWORD Reserved)
Definition: ports.c:789
BOOL WINAPI LocalmonXcvClosePort(HANDLE hXcv)
Definition: xcv.c:502
#define SIGLCMPORT
Definition: precomp.h:31
BOOL WINAPI LocalmonXcvOpenPort(HANDLE hMonitor, PCWSTR pszObject, ACCESS_MASK GrantedAccess, PHANDLE phXcv)
Definition: xcv.c:566
DWORD WINAPI LocalmonXcvDataPort(HANDLE hXcv, PCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded)
Definition: xcv.c:526
struct _LOCALMON_HANDLE * PLOCALMON_HANDLE
#define SIGLCMMON
Definition: precomp.h:30
#define IDS_LOCAL_PORT
Definition: resource.h:10
#define IDS_LOCAL_MONITOR
Definition: resource.h:11
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
__wchar_t WCHAR
Definition: xmlstorage.h:180