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.

552 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. oscode.c
  5. Abstract:
  6. This module contains support routines for the traffic DLL.
  7. Author:
  8. Jim Stewart (jstew) August 14, 1996
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. //#pragma hdrstop
  13. //#include "oscode.h"
  14. //
  15. // function pointers for NT functions to Open driver
  16. //
  17. FARPROC CreateFileNt = NULL;
  18. FARPROC CloseNt = NULL;
  19. FARPROC NtStatusToDosError = NULL;
  20. FARPROC RtlInitUnicodeStringNt = NULL;
  21. PTCHAR NTDLL = L"\\ntdll.dll";
  22. extern PGPC_NOTIFY_REQUEST_RES GpcResCb;
  23. DWORD
  24. OpenDriver(
  25. OUT HANDLE *pHandle,
  26. IN LPCWSTR DriverName
  27. )
  28. /*++
  29. Routine Description:
  30. This function opens a specified drivers control channel.
  31. Arguments:
  32. pHandle - the handle to the opened driver
  33. DriverName - name of the driver to be opened.
  34. Return Value:
  35. Windows Error Code.
  36. --*/
  37. {
  38. NTSTATUS Status = NO_ERROR;
  39. IO_STATUS_BLOCK ioStatusBlock;
  40. OBJECT_ATTRIBUTES objectAttributes;
  41. UNICODE_STRING nameString;
  42. (*RtlInitUnicodeStringNt)(&nameString,DriverName);
  43. InitializeObjectAttributes( &objectAttributes,
  44. &nameString,
  45. OBJ_CASE_INSENSITIVE,
  46. NULL,
  47. NULL);
  48. //
  49. // Open a Handle to the driver.
  50. //
  51. Status = (NTSTATUS)(*CreateFileNt)( pHandle,
  52. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  53. &objectAttributes,
  54. &ioStatusBlock,
  55. NULL,
  56. FILE_ATTRIBUTE_NORMAL,
  57. FILE_SHARE_READ | FILE_SHARE_WRITE,
  58. FILE_OPEN_IF,
  59. 0,
  60. NULL,
  61. 0);
  62. if (Status == STATUS_SUCCESS) {
  63. //
  64. // send an IOCTL for driver notifications
  65. //
  66. // IOCTL is done when the first client registers
  67. // with TC. This is done in another thread so that
  68. // it can be cancelled when there are no clients
  69. // IoRequestNotify(/*pGpcClient*/);
  70. }
  71. return (Status == STATUS_SUCCESS ? 0 : ERROR_OPEN_FAILED);
  72. }
  73. DWORD
  74. DeviceControl(
  75. IN HANDLE FileHandle,
  76. IN HANDLE EventHandle,
  77. IN PIO_APC_ROUTINE ApcRoutine,
  78. IN PVOID ApcContext,
  79. OUT PIO_STATUS_BLOCK pIoStatBlock,
  80. IN ULONG Ioctl,
  81. IN PVOID setBuffer,
  82. IN ULONG setBufferSize,
  83. IN PVOID OutBuffer,
  84. IN ULONG OutBufferSize )
  85. /*++
  86. Routine Description:
  87. This routine issues a device control request to the GPC
  88. Arguments:
  89. FileHandle - Open handle to the GPC driver
  90. Ioctl - The IOCTL to pass to the stack
  91. setBuffer - Data buffer containing the information to be set
  92. setBufferSize - The size of the set data buffer.
  93. Outbuffer - the returned buffer
  94. OutBufferSize - the size
  95. Return Value:
  96. A winerror status value.
  97. --*/
  98. {
  99. NTSTATUS NtStatus = NO_ERROR;
  100. DWORD Status;
  101. if (NTPlatform) {
  102. IF_DEBUG(IOCTLS) {
  103. WSPRINT(("==>DeviceIoControl: Ioctl= %x\n", Ioctl ));
  104. }
  105. NtStatus = NtDeviceIoControlFile( FileHandle,
  106. EventHandle, // Event
  107. ApcRoutine, // when completed
  108. ApcContext, // for ApcRoutine
  109. pIoStatBlock, // for ApcRoutine
  110. Ioctl, // Control code
  111. setBuffer, // Input buffer
  112. setBufferSize, // Input buffer size
  113. OutBuffer, // Output buffer
  114. OutBufferSize ); // Output buffer size
  115. if (ApcRoutine && NT_SUCCESS(NtStatus)) {
  116. Status = ERROR_SIGNAL_PENDING;
  117. IF_DEBUG(IOCTLS) {
  118. WSPRINT(("DeviceIoControl: ApcRoutine defined Status=0x%X\n",
  119. Status ));
  120. }
  121. } else {
  122. Status = MapNtStatus2WinError(NtStatus);
  123. IF_DEBUG(IOCTLS) {
  124. WSPRINT(("DeviceIoControl: NtStatus=0x%X, Status=0x%X\n",
  125. NtStatus, Status ));
  126. }
  127. #if DBG
  128. if (EventHandle) {
  129. IF_DEBUG(IOCTLS) {
  130. WSPRINT(("DeviceIoControl: Event defined\n"));
  131. }
  132. }
  133. #endif
  134. }
  135. } else {
  136. // yoramb - not supporting other OSs for now.
  137. WSPRINT(("DeviceControl: Only Windows NT supported at this time!\n"));
  138. Status = ERROR_NOT_SUPPORTED;
  139. }
  140. IF_DEBUG(IOCTLS) {
  141. WSPRINT(("<==DeviceIoControl: Returned=0x%X\n",
  142. Status ));
  143. }
  144. return( Status );
  145. }
  146. DWORD
  147. InitializeOsSpecific(VOID)
  148. /*++
  149. Routine Description:
  150. Arguments:
  151. status - status to convert:
  152. Return Value:
  153. status
  154. --*/
  155. {
  156. DWORD Status;
  157. OSVERSIONINFO VersionInfo;
  158. //
  159. // determine the type of system we are running on
  160. //
  161. Status = NO_ERROR;
  162. NTPlatform = TRUE;
  163. VersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  164. if (GetVersionEx( &VersionInfo )) {
  165. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
  166. NTPlatform = TRUE;
  167. }
  168. } else {
  169. WSPRINT(("Could not get version\n"));
  170. }
  171. if (!NTPlatform) {
  172. //
  173. // Initially, only NT compatibility is required.
  174. //
  175. return(ERROR_SERVICE_DOES_NOT_EXIST);
  176. } else {
  177. HINSTANCE NtDll;
  178. WCHAR wszNtDllPath[MAX_PATH];
  179. DWORD dwPos = 0;
  180. //
  181. // get the function ptrs to NT specific routines that we need
  182. //
  183. //
  184. // Obtain the path to the system directory.
  185. //
  186. dwPos = (DWORD) GetSystemDirectoryW(wszNtDllPath, MAX_PATH);
  187. if ((dwPos <= 0) || (dwPos >= (MAX_PATH - wcslen(NTDLL) -1)))
  188. {
  189. //
  190. // Either error or not enough room to write the path to ntdll.dll
  191. //
  192. WSPRINT(("InitializeOsSpecific: Failed to load ntdll.dll\n"));
  193. return(FALSE);
  194. }
  195. //
  196. // Concatenate the word "\NTDLL.DLL"
  197. //
  198. wcsncat(&wszNtDllPath[dwPos], NTDLL, wcslen(NTDLL));
  199. //
  200. // Terminate the string
  201. //
  202. wszNtDllPath[dwPos + wcslen(NTDLL)] = '\0';
  203. //
  204. // Finally, load the library.
  205. //
  206. NtDll = LoadLibraryExW(wszNtDllPath, NULL, 0);
  207. if (NtDll == NULL) {
  208. WSPRINT(("InitializeOsSpecific: Failed to load ntdll.dll\n"));
  209. return(FALSE);
  210. }
  211. CreateFileNt = GetProcAddress(NtDll,"NtCreateFile" );
  212. CloseNt = GetProcAddress( NtDll,"NtClose" );
  213. RtlInitUnicodeStringNt = GetProcAddress( NtDll,"RtlInitUnicodeString" );
  214. NtStatusToDosError = GetProcAddress( NtDll,"RtlNtStatusToDosError" );
  215. if ( (CreateFileNt == NULL) ||
  216. (CloseNt == NULL) ||
  217. (RtlInitUnicodeStringNt == NULL) ||
  218. (NtStatusToDosError == NULL) ) {
  219. Status = ERROR_PATH_NOT_FOUND;
  220. } else {
  221. //
  222. // open a handle to the GPC
  223. //
  224. Status = OpenDriver( &pGlobals->GpcFileHandle,
  225. (LPWSTR)DD_GPC_DEVICE_NAME);
  226. if (Status != NO_ERROR){
  227. WSPRINT(("\tThis version of traffic.dll requires kernel traffic control components.\n"));
  228. WSPRINT(("\tIt is unable to find these components.\n"));
  229. WSPRINT(("\tDilithium crystals may be used in their place...\n"));
  230. }
  231. }
  232. }
  233. return( Status );
  234. }
  235. VOID
  236. DeInitializeOsSpecific(VOID)
  237. /*++
  238. Routine Description:
  239. This procedure closes the file handle passed in, in a platform dependent manner.
  240. Arguments:
  241. Handle - the handle to close
  242. Return Value:
  243. status
  244. --*/
  245. {
  246. //
  247. // only on NT do we close the handle, since on Win95,
  248. // we don't actually open a file for Tcp, so there
  249. // is no handle in that case
  250. //
  251. IF_DEBUG(SHUTDOWN) {
  252. WSPRINT(( "DeInitializeOsSpecific: closing the GPC file handle\n" ));
  253. }
  254. if (NTPlatform && pGlobals->GpcFileHandle)
  255. {
  256. (*CloseNt)( pGlobals->GpcFileHandle );
  257. }
  258. IF_DEBUG(SHUTDOWN) {
  259. WSPRINT(( "<==DeInitializeOsSpecific: exit...\n" ));
  260. }
  261. }
  262. DWORD
  263. MapNtStatus2WinError(
  264. NTSTATUS NtStatus
  265. )
  266. /*++
  267. Routine Description:
  268. This procedure maps the ntstatus return codes Winerrors.
  269. Arguments:
  270. status - status to convert:
  271. Return Value:
  272. status
  273. --*/
  274. {
  275. DWORD stat;
  276. switch (NtStatus) {
  277. case STATUS_SUCCESS:
  278. stat = NO_ERROR;
  279. break;
  280. case STATUS_INSUFFICIENT_RESOURCES:
  281. stat = ERROR_NO_SYSTEM_RESOURCES;
  282. break;
  283. case STATUS_BUFFER_OVERFLOW:
  284. stat = ERROR_MORE_DATA;
  285. break;
  286. case STATUS_INVALID_PARAMETER:
  287. stat = ERROR_INVALID_PARAMETER;
  288. break;
  289. case STATUS_TRANSACTION_TIMED_OUT:
  290. stat = ERROR_TIMEOUT;
  291. break;
  292. case STATUS_REQUEST_NOT_ACCEPTED:
  293. stat = ERROR_NETWORK_BUSY;
  294. break;
  295. case STATUS_NOT_SUPPORTED:
  296. case STATUS_UNSUCCESSFUL:
  297. stat = ERROR_NOT_SUPPORTED;
  298. break;
  299. case STATUS_BUFFER_TOO_SMALL:
  300. stat = ERROR_INSUFFICIENT_BUFFER;
  301. break;
  302. case STATUS_PENDING:
  303. stat = ERROR_SIGNAL_PENDING;
  304. break;
  305. case STATUS_OBJECT_NAME_NOT_FOUND:
  306. stat = ERROR_PATH_NOT_FOUND;
  307. break;
  308. case STATUS_DEVICE_NOT_READY:
  309. stat = ERROR_NOT_READY;
  310. break;
  311. case STATUS_NOT_FOUND:
  312. stat = ERROR_NOT_FOUND;
  313. break;
  314. case STATUS_DUPLICATE_NAME:
  315. stat = ERROR_DUPLICATE_FILTER;
  316. break;
  317. case STATUS_INVALID_HANDLE:
  318. stat = ERROR_INVALID_HANDLE;
  319. break;
  320. case STATUS_DIRECTORY_NOT_EMPTY:
  321. stat = ERROR_TC_SUPPORTED_OBJECTS_EXIST;
  322. break;
  323. case STATUS_TOO_MANY_OPENED_FILES:
  324. stat = ERROR_TOO_MANY_OPEN_FILES;
  325. break;
  326. case STATUS_NOT_IMPLEMENTED:
  327. stat = ERROR_CALL_NOT_IMPLEMENTED;
  328. break;
  329. case STATUS_DATA_ERROR:
  330. stat = ERROR_INVALID_DATA;
  331. break;
  332. case NDIS_STATUS_INCOMPATABLE_QOS:
  333. stat = ERROR_INCOMPATABLE_QOS;
  334. break;
  335. case QOS_STATUS_INVALID_SERVICE_TYPE:
  336. stat = ERROR_INVALID_SERVICE_TYPE;
  337. break;
  338. case QOS_STATUS_INVALID_TOKEN_RATE:
  339. stat = ERROR_INVALID_TOKEN_RATE;
  340. break;
  341. case QOS_STATUS_INVALID_PEAK_RATE:
  342. stat = ERROR_INVALID_PEAK_RATE;
  343. break;
  344. case QOS_STATUS_INVALID_SD_MODE:
  345. stat = ERROR_INVALID_SD_MODE;
  346. break;
  347. case QOS_STATUS_INVALID_QOS_PRIORITY:
  348. stat = ERROR_INVALID_QOS_PRIORITY;
  349. break;
  350. case QOS_STATUS_INVALID_TRAFFIC_CLASS:
  351. stat = ERROR_INVALID_TRAFFIC_CLASS;
  352. break;
  353. case QOS_STATUS_TC_OBJECT_LENGTH_INVALID:
  354. stat = ERROR_TC_OBJECT_LENGTH_INVALID;
  355. break;
  356. case QOS_STATUS_INVALID_FLOW_MODE:
  357. stat = ERROR_INVALID_FLOW_MODE;
  358. break;
  359. case QOS_STATUS_INVALID_DIFFSERV_FLOW:
  360. stat = ERROR_INVALID_DIFFSERV_FLOW;
  361. break;
  362. case QOS_STATUS_DS_MAPPING_EXISTS:
  363. stat = ERROR_DS_MAPPING_EXISTS;
  364. break;
  365. case QOS_STATUS_INVALID_SHAPE_RATE:
  366. stat = ERROR_INVALID_SHAPE_RATE;
  367. break;
  368. case STATUS_NETWORK_UNREACHABLE:
  369. stat = ERROR_NETWORK_UNREACHABLE;
  370. break;
  371. case QOS_STATUS_INVALID_DS_CLASS:
  372. stat = ERROR_INVALID_DS_CLASS;
  373. break;
  374. case ERROR_TOO_MANY_OPEN_FILES:
  375. stat = ERROR_TOO_MANY_CLIENTS;
  376. break;
  377. default:
  378. stat = ERROR_GEN_FAILURE;
  379. }
  380. return stat;
  381. }