Leaked source code of windows server 2003
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.

553 lines
13 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) -2)))
  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. FreeLibrary(NtDll);
  220. Status = ERROR_PATH_NOT_FOUND;
  221. } else {
  222. //
  223. // open a handle to the GPC
  224. //
  225. Status = OpenDriver( &pGlobals->GpcFileHandle,
  226. (LPWSTR)DD_GPC_DEVICE_NAME);
  227. if (Status != NO_ERROR){
  228. WSPRINT(("\tThis version of traffic.dll requires kernel traffic control components.\n"));
  229. WSPRINT(("\tIt is unable to find these components.\n"));
  230. WSPRINT(("\tDilithium crystals may be used in their place...\n"));
  231. }
  232. }
  233. }
  234. return( Status );
  235. }
  236. VOID
  237. DeInitializeOsSpecific(VOID)
  238. /*++
  239. Routine Description:
  240. This procedure closes the file handle passed in, in a platform dependent manner.
  241. Arguments:
  242. Handle - the handle to close
  243. Return Value:
  244. status
  245. --*/
  246. {
  247. //
  248. // only on NT do we close the handle, since on Win95,
  249. // we don't actually open a file for Tcp, so there
  250. // is no handle in that case
  251. //
  252. IF_DEBUG(SHUTDOWN) {
  253. WSPRINT(( "DeInitializeOsSpecific: closing the GPC file handle\n" ));
  254. }
  255. if (NTPlatform && pGlobals->GpcFileHandle)
  256. {
  257. (*CloseNt)( pGlobals->GpcFileHandle );
  258. }
  259. IF_DEBUG(SHUTDOWN) {
  260. WSPRINT(( "<==DeInitializeOsSpecific: exit...\n" ));
  261. }
  262. }
  263. DWORD
  264. MapNtStatus2WinError(
  265. NTSTATUS NtStatus
  266. )
  267. /*++
  268. Routine Description:
  269. This procedure maps the ntstatus return codes Winerrors.
  270. Arguments:
  271. status - status to convert:
  272. Return Value:
  273. status
  274. --*/
  275. {
  276. DWORD stat;
  277. switch (NtStatus) {
  278. case STATUS_SUCCESS:
  279. stat = NO_ERROR;
  280. break;
  281. case STATUS_INSUFFICIENT_RESOURCES:
  282. stat = ERROR_NO_SYSTEM_RESOURCES;
  283. break;
  284. case STATUS_BUFFER_OVERFLOW:
  285. stat = ERROR_MORE_DATA;
  286. break;
  287. case STATUS_INVALID_PARAMETER:
  288. stat = ERROR_INVALID_PARAMETER;
  289. break;
  290. case STATUS_TRANSACTION_TIMED_OUT:
  291. stat = ERROR_TIMEOUT;
  292. break;
  293. case STATUS_REQUEST_NOT_ACCEPTED:
  294. stat = ERROR_NETWORK_BUSY;
  295. break;
  296. case STATUS_NOT_SUPPORTED:
  297. case STATUS_UNSUCCESSFUL:
  298. stat = ERROR_NOT_SUPPORTED;
  299. break;
  300. case STATUS_BUFFER_TOO_SMALL:
  301. stat = ERROR_INSUFFICIENT_BUFFER;
  302. break;
  303. case STATUS_PENDING:
  304. stat = ERROR_SIGNAL_PENDING;
  305. break;
  306. case STATUS_OBJECT_NAME_NOT_FOUND:
  307. stat = ERROR_PATH_NOT_FOUND;
  308. break;
  309. case STATUS_DEVICE_NOT_READY:
  310. stat = ERROR_NOT_READY;
  311. break;
  312. case STATUS_NOT_FOUND:
  313. stat = ERROR_NOT_FOUND;
  314. break;
  315. case STATUS_DUPLICATE_NAME:
  316. stat = ERROR_DUPLICATE_FILTER;
  317. break;
  318. case STATUS_INVALID_HANDLE:
  319. stat = ERROR_INVALID_HANDLE;
  320. break;
  321. case STATUS_DIRECTORY_NOT_EMPTY:
  322. stat = ERROR_TC_SUPPORTED_OBJECTS_EXIST;
  323. break;
  324. case STATUS_TOO_MANY_OPENED_FILES:
  325. stat = ERROR_TOO_MANY_OPEN_FILES;
  326. break;
  327. case STATUS_NOT_IMPLEMENTED:
  328. stat = ERROR_CALL_NOT_IMPLEMENTED;
  329. break;
  330. case STATUS_DATA_ERROR:
  331. stat = ERROR_INVALID_DATA;
  332. break;
  333. case NDIS_STATUS_INCOMPATABLE_QOS:
  334. stat = ERROR_INCOMPATABLE_QOS;
  335. break;
  336. case QOS_STATUS_INVALID_SERVICE_TYPE:
  337. stat = ERROR_INVALID_SERVICE_TYPE;
  338. break;
  339. case QOS_STATUS_INVALID_TOKEN_RATE:
  340. stat = ERROR_INVALID_TOKEN_RATE;
  341. break;
  342. case QOS_STATUS_INVALID_PEAK_RATE:
  343. stat = ERROR_INVALID_PEAK_RATE;
  344. break;
  345. case QOS_STATUS_INVALID_SD_MODE:
  346. stat = ERROR_INVALID_SD_MODE;
  347. break;
  348. case QOS_STATUS_INVALID_QOS_PRIORITY:
  349. stat = ERROR_INVALID_QOS_PRIORITY;
  350. break;
  351. case QOS_STATUS_INVALID_TRAFFIC_CLASS:
  352. stat = ERROR_INVALID_TRAFFIC_CLASS;
  353. break;
  354. case QOS_STATUS_TC_OBJECT_LENGTH_INVALID:
  355. stat = ERROR_TC_OBJECT_LENGTH_INVALID;
  356. break;
  357. case QOS_STATUS_INVALID_FLOW_MODE:
  358. stat = ERROR_INVALID_FLOW_MODE;
  359. break;
  360. case QOS_STATUS_INVALID_DIFFSERV_FLOW:
  361. stat = ERROR_INVALID_DIFFSERV_FLOW;
  362. break;
  363. case QOS_STATUS_DS_MAPPING_EXISTS:
  364. stat = ERROR_DS_MAPPING_EXISTS;
  365. break;
  366. case QOS_STATUS_INVALID_SHAPE_RATE:
  367. stat = ERROR_INVALID_SHAPE_RATE;
  368. break;
  369. case STATUS_NETWORK_UNREACHABLE:
  370. stat = ERROR_NETWORK_UNREACHABLE;
  371. break;
  372. case QOS_STATUS_INVALID_DS_CLASS:
  373. stat = ERROR_INVALID_DS_CLASS;
  374. break;
  375. case ERROR_TOO_MANY_OPEN_FILES:
  376. stat = ERROR_TOO_MANY_CLIENTS;
  377. break;
  378. default:
  379. stat = ERROR_GEN_FAILURE;
  380. }
  381. return stat;
  382. }