2 * PROJECT: ReactOS Local Port Monitor
3 * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
4 * PURPOSE: Main functions
5 * COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
13 PCWSTR pwszLocalMonitor
;
17 static MONITOR2 _MonitorFunctions
= {
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
29 NULL
, // pfnConfigurePort
30 NULL
, // pfnDeletePort
31 LocalmonGetPrinterDataFromPort
, // pfnGetPrinterDataFromPort
32 LocalmonSetPortTimeOuts
, // pfnSetPortTimeOuts
33 LocalmonXcvOpenPort
, // pfnXcvOpenPort
34 LocalmonXcvDataPort
, // pfnXcvDataPort
35 LocalmonXcvClosePort
, // pfnXcvClosePort
36 LocalmonShutdown
, // pfnShutdown
37 NULL
, // pfnSendRecvBidiDataFromPort
42 _LoadResources(HINSTANCE hinstDLL
)
44 LoadStringW(hinstDLL
, IDS_LOCAL_MONITOR
, (PWSTR
)&pwszLocalMonitor
, 0);
45 cbLocalMonitor
= (wcslen(pwszLocalMonitor
) + 1) * sizeof(WCHAR
);
47 LoadStringW(hinstDLL
, IDS_LOCAL_PORT
, (PWSTR
)&pwszLocalPort
, 0);
48 cbLocalPort
= (wcslen(pwszLocalPort
) + 1) * sizeof(WCHAR
);
52 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
56 case DLL_PROCESS_ATTACH
:
57 DisableThreadLibraryCalls(hinstDLL
);
58 _LoadResources(hinstDLL
);
66 LocalmonShutdown(HANDLE hMonitor
)
68 PLOCALMON_HANDLE pLocalmon
;
71 pLocalmon
= (PLOCALMON_HANDLE
)hMonitor
;
73 // Close all virtual file ports.
74 while (!IsListEmpty(&pLocalmon
->FilePorts
))
76 pPort
= CONTAINING_RECORD(&pLocalmon
->FilePorts
.Flink
, LOCALMON_PORT
, Entry
);
77 LocalmonClosePort((HANDLE
)pPort
);
80 // Now close all regular ports and remove them from the list.
81 while (!IsListEmpty(&pLocalmon
->Ports
))
83 pPort
= CONTAINING_RECORD(&pLocalmon
->Ports
.Flink
, LOCALMON_PORT
, Entry
);
84 RemoveEntryList(&pPort
->Entry
);
85 LocalmonClosePort((HANDLE
)pPort
);
88 // Finally free the memory for the LOCALMON_HANDLE structure itself.
89 DllFreeSplMem(pLocalmon
);
93 InitializePrintMonitor2(PMONITORINIT pMonitorInit
, PHANDLE phMonitor
)
101 PMONITOR2 pReturnValue
= NULL
;
102 PLOCALMON_HANDLE pLocalmon
;
103 PLOCALMON_PORT pPort
= NULL
;
105 // Create a new LOCALMON_HANDLE structure.
106 pLocalmon
= DllAllocSplMem(sizeof(LOCALMON_HANDLE
));
107 InitializeListHead(&pLocalmon
->FilePorts
);
108 InitializeListHead(&pLocalmon
->Ports
);
110 // The Local Spooler Port Monitor doesn't need to care about the given registry key and functions.
111 // Instead it uses a well-known registry key for getting its information about local ports. Open this one.
112 dwErrorCode
= (DWORD
)RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports", 0, KEY_READ
, &hKey
);
113 if (dwErrorCode
!= ERROR_SUCCESS
)
115 ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode
);
119 // Get the number of ports and the length of the largest port name.
120 dwErrorCode
= (DWORD
)RegQueryInfoKeyW(hKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &dwPortCount
, &cchMaxPortName
, NULL
, NULL
, NULL
);
121 if (dwErrorCode
!= ERROR_SUCCESS
)
123 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode
);
127 // Loop through all ports.
128 for (i
= 0; i
< dwPortCount
; i
++)
130 // Allocate memory for a new LOCALMON_PORT structure and its name.
131 pPort
= DllAllocSplMem(sizeof(LOCALMON_PORT
) + (cchMaxPortName
+ 1) * sizeof(WCHAR
));
134 dwErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
135 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
139 pPort
->hFile
= INVALID_HANDLE_VALUE
;
140 pPort
->pwszPortName
= (PWSTR
)((PBYTE
)pPort
+ sizeof(LOCALMON_PORT
));
142 // Get the port name.
143 cchPortName
= cchMaxPortName
+ 1;
144 dwErrorCode
= (DWORD
)RegEnumValueW(hKey
, i
, pPort
->pwszPortName
, &cchPortName
, NULL
, NULL
, NULL
, NULL
);
145 if (dwErrorCode
!= ERROR_SUCCESS
)
147 ERR("RegEnumValueW failed with status %lu!\n", dwErrorCode
);
151 // This Port Monitor supports COM, FILE and LPT ports. Skip all others.
152 if (_wcsnicmp(pPort
->pwszPortName
, L
"COM", 3) != 0 && _wcsicmp(pPort
->pwszPortName
, L
"FILE:") != 0 && _wcsnicmp(pPort
->pwszPortName
, L
"LPT", 3) != 0)
154 DllFreeSplMem(pPort
);
158 // Add it to the list.
159 InsertTailList(&pLocalmon
->Ports
, &pPort
->Entry
);
161 // Don't let the cleanup routine free this.
165 // Return our handle and the Print Monitor functions.
166 *phMonitor
= (HANDLE
)pLocalmon
;
167 pReturnValue
= &_MonitorFunctions
;
168 dwErrorCode
= ERROR_SUCCESS
;
172 DllFreeSplMem(pPort
);
174 SetLastError(dwErrorCode
);