Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

327 lines
7.4 KiB

  1. /*
  2. * Copyright (c) Microsoft Corporation
  3. *
  4. * Module Name :
  5. * utils.c
  6. *
  7. * Some utility functions used by the service.
  8. *
  9. * Sadagopan Rajaram -- Oct 18, 1999
  10. *
  11. */
  12. #include "tcsrv.h"
  13. #include <ntddser.h>
  14. #include "tcsrvc.h"
  15. #include "proto.h"
  16. PCOM_PORT_INFO
  17. FindDevice(
  18. LPTSTR device,
  19. int *pIndex
  20. )
  21. /*++
  22. Searches through the global list and returns the COM port with the
  23. correct name
  24. Remember that the shared global variables are not locked during this
  25. function call
  26. --*/
  27. {
  28. PCOM_PORT_INFO pTemp;
  29. int i=ComPorts-1;
  30. pTemp = ComPortInfo;
  31. while(pTemp){
  32. if(!((_tcscmp(pTemp->Device.Buffer,device)) &&
  33. (_tcscmp(pTemp->Name.Buffer, device))))
  34. break;
  35. pTemp = pTemp->Next;
  36. i--;
  37. }
  38. *pIndex = i;
  39. return pTemp;
  40. }
  41. LONG
  42. GetNextParameter(
  43. HKEY hKey,
  44. DWORD dwIndex,
  45. PHKEY pChild,
  46. LPTSTR *Name
  47. )
  48. /*++
  49. Gets the name of the Com Port. It is a user defined name and has nothing
  50. to do with the device name in NT.
  51. Return -
  52. A filled in Com port info, else NULL if end of Parameters is reached.
  53. --*/
  54. {
  55. LONG RetVal;
  56. // Registry names cannot be longer than 256 characters.
  57. TCHAR lpName[MAX_REGISTRY_NAME_SIZE];
  58. DWORD lpcName;
  59. FILETIME lpftLastWriteTime;
  60. lpcName = MAX_REGISTRY_NAME_SIZE;
  61. RetVal = RegEnumKeyEx(hKey,
  62. dwIndex,
  63. lpName,
  64. &lpcName,
  65. NULL,
  66. NULL,
  67. NULL,
  68. &lpftLastWriteTime
  69. );
  70. if(RetVal != ERROR_SUCCESS){
  71. RegCloseKey(hKey);
  72. return RetVal;
  73. }
  74. *Name = (LPTSTR) TCAllocate(sizeof(TCHAR)*(lpcName+1),"Registry key");
  75. if((*Name) == NULL){
  76. RegCloseKey(hKey);
  77. return(ERROR_NOT_ENOUGH_MEMORY);
  78. }
  79. _tcscpy((*Name),lpName);
  80. RetVal= RegOpenKeyEx(hKey,
  81. lpName, // subkey name
  82. 0, // reserved
  83. KEY_ALL_ACCESS, // security access mask
  84. pChild
  85. );
  86. if(RetVal != ERROR_SUCCESS){
  87. RegCloseKey(hKey);
  88. }
  89. return RetVal;
  90. }
  91. LONG
  92. GetNameOfDeviceFromRegistry(
  93. HKEY hKey,
  94. LPTSTR *device
  95. )
  96. /*++
  97. Gets the NT device Name. If there is no device name, it is an error.
  98. Return-
  99. Device Name like L"\\device\\serial0"
  100. --*/
  101. {
  102. LONG RetVal;
  103. DWORD lpType=0;
  104. LPTSTR lpData = NULL;
  105. DWORD lpcbData=0;
  106. RetVal = RegQueryValueEx(hKey,
  107. _T("Device"),
  108. NULL,
  109. &lpType,
  110. (LPBYTE)lpData,
  111. &lpcbData
  112. );
  113. if((RetVal != ERROR_SUCCESS)
  114. &&(RetVal != ERROR_MORE_DATA)){
  115. RegCloseKey(hKey);
  116. return RetVal;
  117. }
  118. lpData = (LPTSTR) TCAllocate(lpcbData, "Device Name");
  119. if(lpData == NULL){
  120. RegCloseKey(hKey);
  121. return ERROR_NOT_ENOUGH_MEMORY;
  122. }
  123. RetVal = RegQueryValueEx(hKey,
  124. _T("Device"),
  125. NULL,
  126. &lpType,
  127. (LPBYTE)lpData,
  128. &lpcbData
  129. );
  130. if(RetVal != ERROR_SUCCESS){
  131. RegCloseKey(hKey);
  132. TCFree(lpData);
  133. return RetVal;
  134. }
  135. *device = lpData;
  136. return ERROR_SUCCESS;
  137. }
  138. PCOM_PORT_INFO
  139. GetComPortParameters(
  140. HKEY hKey
  141. )
  142. {
  143. PCOM_PORT_INFO pComPortInfo;
  144. DWORD dwordsize;
  145. ULONG RetVal;
  146. DWORD data;
  147. dwordsize = sizeof(DWORD);
  148. pComPortInfo = (PCOM_PORT_INFO)TCAllocate(sizeof(COM_PORT_INFO),"Com Port Data");
  149. if(pComPortInfo== NULL){
  150. RegCloseKey(hKey);
  151. return NULL;
  152. }
  153. data = DEFAULT_BAUD_RATE;
  154. RetVal = RegQueryValueEx(hKey,
  155. _T("Baud Rate"),
  156. NULL,
  157. NULL,
  158. (LPBYTE) &data,
  159. &(dwordsize)
  160. );
  161. pComPortInfo->BaudRate = (ULONG) data;
  162. data = STOP_BIT_1;
  163. RetVal = RegQueryValueEx(hKey,
  164. _T("Stop Bits"),
  165. NULL,
  166. NULL,
  167. (LPBYTE) &data,
  168. &(dwordsize)
  169. );
  170. pComPortInfo->StopBits = (UCHAR) data;
  171. data = NO_PARITY;
  172. RetVal = RegQueryValueEx(hKey,
  173. _T("Stop Bits"),
  174. NULL,
  175. NULL,
  176. (LPBYTE) &data,
  177. &(dwordsize)
  178. );
  179. pComPortInfo->Parity = (UCHAR) data;
  180. data = SERIAL_DATABITS_8;
  181. RetVal = RegQueryValueEx(hKey,
  182. _T("Word Length"),
  183. NULL,
  184. NULL,
  185. (LPBYTE) &data,
  186. &(dwordsize)
  187. );
  188. pComPortInfo->WordLength = (UCHAR) data;
  189. return pComPortInfo;
  190. }
  191. VOID
  192. FreeComPortInfo(
  193. PCOM_PORT_INFO pTemp
  194. )
  195. {
  196. if(pTemp == NULL) return;
  197. if (pTemp->Device.Buffer) {
  198. TCFree(pTemp->Device.Buffer);
  199. }
  200. if(pTemp->Name.Buffer){
  201. TCFree(pTemp->Name.Buffer);
  202. }
  203. NtClose(pTemp->Events[1]);
  204. NtClose(pTemp->Events[2]);
  205. NtClose(pTemp->Events[3]);
  206. NtClose(pTemp->TerminateEvent);
  207. NtClose(pTemp->WriteOverlapped.hEvent);
  208. DeleteCriticalSection(&(pTemp->Mutex));
  209. TCFree(pTemp);
  210. return;
  211. }
  212. VOID Enqueue(
  213. PCOM_PORT_INFO pComPortInfo
  214. )
  215. {
  216. int i,size,j,k;
  217. size = (int) pComPortInfo->Overlapped.InternalHigh;
  218. j = pComPortInfo->Tail;
  219. k = pComPortInfo->Head;
  220. for(i=0;i<size;i++){
  221. (pComPortInfo->Queue)[j] = (pComPortInfo->Buffer)[i];
  222. j = (j+1)% MAX_QUEUE_SIZE;
  223. if(k==j){
  224. k = (k+1)%MAX_QUEUE_SIZE;
  225. }
  226. }
  227. pComPortInfo->Head = k;
  228. pComPortInfo->Tail =j;
  229. return;
  230. }
  231. int GetBufferInfo(
  232. PCONNECTION_INFO pConnection,
  233. PCOM_PORT_INFO pComPortInfo
  234. )
  235. {
  236. int i,size;
  237. int Status;
  238. size = 0;
  239. for(i=pComPortInfo->Head; (i != pComPortInfo->Tail ); i=(i+1)%(MAX_QUEUE_SIZE)){
  240. (pConnection->buffer)[size] = (pComPortInfo->Queue)[i];
  241. size++;
  242. if(size == MAX_BUFFER_SIZE){
  243. Status=send(pConnection->Socket, pConnection->buffer, size, 0);
  244. if(Status == SOCKET_ERROR){
  245. return Status;
  246. }
  247. size = 0;
  248. }
  249. }
  250. if(size){
  251. Status = send(pConnection->Socket, pConnection->buffer, size, 0);
  252. if(Status == SOCKET_ERROR){
  253. return Status;
  254. }
  255. }
  256. return 0;
  257. }
  258. LONG
  259. TCLock(
  260. PHANDLE lock
  261. )
  262. {
  263. LONG RetVal;
  264. (*lock) = CreateMutex(NULL,
  265. FALSE,
  266. TCSERV_MUTEX_NAME
  267. );
  268. if ((*lock)) {
  269. RetVal = WaitForSingleObject(*lock,INFINITE);
  270. if (RetVal == WAIT_FAILED) {
  271. return GetLastError();
  272. }
  273. else{
  274. return ERROR_SUCCESS;
  275. }
  276. }
  277. else{
  278. return GetLastError();
  279. }
  280. }
  281. VOID
  282. TCUnlock(
  283. HANDLE lock
  284. )
  285. {
  286. if (lock) {
  287. ReleaseMutex(lock);
  288. CloseHandle(lock);
  289. }
  290. return;
  291. }