ReactOS  0.4.15-dev-1377-ga59cecd
tools.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: Various support functions shared by multiple files
5  * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
23 BOOL
24 DoesPortExist(PCWSTR pwszPortName)
25 {
26  BOOL bReturnValue = FALSE;
27  DWORD cbNeeded;
28  DWORD dwErrorCode;
29  DWORD dwReturned;
30  DWORD i;
32  PPORT_INFO_1W pPortInfo1 = NULL;
33 
34  // Determine the required buffer size.
35  EnumPortsW(NULL, 1, NULL, 0, &cbNeeded, &dwReturned);
37  {
38  dwErrorCode = GetLastError();
39  ERR("EnumPortsW failed with error %lu!\n", dwErrorCode);
40  goto Cleanup;
41  }
42 
43  // Allocate a buffer large enough.
44  pPortInfo1 = DllAllocSplMem(cbNeeded);
45  if (!pPortInfo1)
46  {
47  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
48  ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
49  goto Cleanup;
50  }
51 
52  // Now get the actual port information.
53  if (!EnumPortsW(NULL, 1, (PBYTE)pPortInfo1, cbNeeded, &cbNeeded, &dwReturned))
54  {
55  dwErrorCode = GetLastError();
56  ERR("EnumPortsW failed with error %lu!\n", dwErrorCode);
57  goto Cleanup;
58  }
59 
60  // We were successful! Loop through all returned ports.
61  dwErrorCode = ERROR_SUCCESS;
62  p = pPortInfo1;
63 
64  for (i = 0; i < dwReturned; i++)
65  {
66  // Check if this existing port matches our queried one.
67  if (wcsicmp(p->pName, pwszPortName) == 0)
68  {
69  bReturnValue = TRUE;
70  goto Cleanup;
71  }
72 
73  p++;
74  }
75 
76 Cleanup:
77  if (pPortInfo1)
78  DllFreeSplMem(pPortInfo1);
79 
80  SetLastError(dwErrorCode);
81  return bReturnValue;
82 }
83 
84 DWORD
86 {
87  DWORD cbBuffer;
88  DWORD dwReturnValue = 90; // Use 90 seconds as default if we fail to read from registry.
89  HKEY hKey;
90  LSTATUS lStatus;
91 
92  // Six digits is the most you can enter in Windows' LocalUI.dll.
93  // Larger values make it crash, so introduce a limit here.
94  WCHAR wszBuffer[6 + 1];
95 
96  // Open the key where our value is stored.
97  lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows", 0, KEY_READ, &hKey);
98  if (lStatus != ERROR_SUCCESS)
99  {
100  ERR("RegOpenKeyExW failed with status %ld!\n", lStatus);
101  goto Cleanup;
102  }
103 
104  // Query the value.
105  cbBuffer = sizeof(wszBuffer);
106  lStatus = RegQueryValueExW(hKey, L"TransmissionRetryTimeout", NULL, NULL, (PBYTE)wszBuffer, &cbBuffer);
107  if (lStatus != ERROR_SUCCESS)
108  {
109  ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
110  goto Cleanup;
111  }
112 
113  // Return it converted to a DWORD.
114  dwReturnValue = wcstoul(wszBuffer, NULL, 10);
115 
116 Cleanup:
117  if (hKey)
118  RegCloseKey(hKey);
119 
120  return dwReturnValue;
121 }
122 
141 DWORD
142 GetPortNameWithoutColon(PCWSTR pwszPortName, PWSTR* ppwszPortNameWithoutColon)
143 {
144  DWORD cchPortNameWithoutColon;
145 
146  // Compute the string length of pwszPortNameWithoutColon.
147  cchPortNameWithoutColon = wcslen(pwszPortName) - 1;
148 
149  // Check if pwszPortName really has a colon as the last character.
150  if (pwszPortName[cchPortNameWithoutColon] != L':')
152 
153  // Allocate the output buffer.
154  *ppwszPortNameWithoutColon = DllAllocSplMem((cchPortNameWithoutColon + 1) * sizeof(WCHAR));
155  if (!*ppwszPortNameWithoutColon)
156  {
157  ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
159  }
160 
161  // Copy the port name without colon into the buffer.
162  // The buffer is already zero-initialized, so no additional null-termination is necessary.
163  CopyMemory(*ppwszPortNameWithoutColon, pwszPortName, cchPortNameWithoutColon * sizeof(WCHAR));
164 
165  return ERROR_SUCCESS;
166 }
167 
182 static __inline BOOL
183 _IsNEPort(PCWSTR pwszPortName)
184 {
185  PCWSTR p = pwszPortName;
186 
187  // First character needs to be 'N' (uppercase or lowercase)
188  if (*p != L'N' && *p != L'n')
189  return FALSE;
190 
191  // Next character needs to be 'E' (uppercase or lowercase)
192  p++;
193  if (*p != L'E' && *p != L'e')
194  return FALSE;
195 
196  // An optional hyphen may follow now.
197  p++;
198  if (*p == L'-')
199  p++;
200 
201  // Now an arbitrary number of digits may follow.
202  while (*p >= L'0' && *p <= L'9')
203  p++;
204 
205  // Finally, the virtual Ne port must be terminated by a colon.
206  if (*p != ':')
207  return FALSE;
208 
209  // If this is the end of the string, we have a virtual Ne port.
210  p++;
211  return (*p == L'\0');
212 }
213 
214 DWORD
216 {
217  HANDLE hfile;
218 
219  if (!wcsncmp(name, L"LPT", ARRAYSIZE(L"LPT") - 1) )
220  return PORT_IS_LPT;
221 
222  if (!wcsncmp(name, L"COM", ARRAYSIZE(L"COM") - 1) )
223  return PORT_IS_COM;
224 
225  if (!lstrcmpW(name, L"FILE:") )
226  return PORT_IS_FILE;
227 
228 // if (name[0] == '/')
229 // return PORT_IS_UNIXNAME;
230 
231 // if (name[0] == '|')
232 // return PORT_IS_PIPE;
233 
234  if ( _IsNEPort( name ) )
235  return PORT_IS_VNET;
236 
237  if (!wcsncmp(name, L"XPS", ARRAYSIZE(L"XPS") - 1))
238  return PORT_IS_XPS;
239 
240  /* Must be a file or a directory. Does the file exist ? */
242 
243  FIXME("%p for OPEN_EXISTING on %s\n", hfile, debugstr_w(name));
244 
245  if (hfile == INVALID_HANDLE_VALUE)
246  {
247  /* Can we create the file? */
249  FIXME("%p for OPEN_ALWAYS\n", hfile);
250  }
251 
252  if (hfile != INVALID_HANDLE_VALUE)
253  {
254  CloseHandle(hfile); FIXME("PORT_IS_FILENAME %d\n",PORT_IS_FILENAME);
255  return PORT_IS_FILENAME;
256  }
257  FIXME("PORT_IS_UNKNOWN %d\n",PORT_IS_UNKNOWN);
258  /* We can't use the name. use GetLastError() for the reason */
259  return PORT_IS_UNKNOWN;
260 }
#define PORT_IS_FILENAME
Definition: spoolss.h:18
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define CloseHandle
Definition: compat.h:598
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define PORT_IS_UNKNOWN
Definition: spoolss.h:14
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
BOOL DoesPortExist(PCWSTR pwszPortName)
Definition: tools.c:24
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
DWORD GetLPTTransmissionRetryTimeout(VOID)
Definition: tools.c:85
#define PORT_IS_COM
Definition: spoolss.h:16
DWORD GetPortNameWithoutColon(PCWSTR pwszPortName, PWSTR *ppwszPortNameWithoutColon)
Definition: tools.c:142
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:111
#define OPEN_EXISTING
Definition: compat.h:634
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CopyMemory
Definition: winbase.h:1646
#define FILE_FLAG_DELETE_ON_CLOSE
Definition: disk.h:42
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
#define OPEN_ALWAYS
Definition: disk.h:70
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define wcsicmp
Definition: compat.h:15
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR Cleanup[]
Definition: register.c:80
#define PORT_IS_LPT
Definition: spoolss.h:15
#define ERR(fmt,...)
Definition: debug.h:110
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
#define PORT_IS_XPS
Definition: spoolss.h:23
FxAutoRegKey hKey
#define PORT_IS_FILE
Definition: spoolss.h:17
DWORD GetTypeFromName(LPCWSTR name)
Definition: tools.c:215
#define NULL
Definition: types.h:112
#define CreateFileW
Definition: compat.h:600
Definition: name.c:38
#define PORT_IS_VNET
Definition: spoolss.h:22
static __inline BOOL _IsNEPort(PCWSTR pwszPortName)
Definition: tools.c:183
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
WINBOOL WINAPI EnumPortsW(LPWSTR pName, DWORD Level, LPBYTE pPorts, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
GLfloat GLfloat p
Definition: glext.h:8902
BYTE * PBYTE
Definition: pedump.c:66
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10