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.

496 lines
21 KiB

  1. #include <nt.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "ws2ifsl.h"
  5. HANDLE ApcThreadHdl;
  6. HANDLE ProcessFile;
  7. char TestString[]="WS2IFSL";
  8. DWORD WINAPI
  9. ApcThread (
  10. PVOID param
  11. );
  12. VOID CALLBACK
  13. ExitThreadApc (
  14. DWORD param
  15. );
  16. VOID
  17. Ws2ifslApc (
  18. IN PWS2IFSL_APC_REQUEST Request,
  19. IN PVOID RequestCtx,
  20. IN PVOID SocketCtx
  21. );
  22. int _cdecl
  23. main (
  24. int argc,
  25. char *argv[]
  26. ) {
  27. UCHAR fullEaBuffer[FIELD_OFFSET(FILE_FULL_EA_INFORMATION,
  28. EaName[WS2IFSL_PROCESS_EA_NAME_LENGTH+1]);
  29. PFILE_FULL_EA_INFORMATION fileEa;
  30. OBJECT_ATTRIBUTES fileAttr;
  31. UNICODE_STRING fileName;
  32. NTSTATUS status;
  33. DWORD apcThreadId;
  34. HANDLE hEvent;
  35. DWORD rc;
  36. BOOL res;
  37. hEvent = CreateEvent (NULL, TRUE, FALSE, NULL); // manual reset event
  38. if (hEvent==NULL) {
  39. printf ("Could not create event.\n");
  40. return 1;
  41. }
  42. RtlInitUnicodeString (fileName, WS2IFSL_DEVICE_NAME);
  43. InitializeObjectAttributes (&fileAttr,
  44. fileName,
  45. 0, // Attributes
  46. NULL, // Root directory
  47. NULL); // Security descriptor
  48. fileEa = (PPFILE_FULL_EA_INFORMATION)fullEaBuffer;
  49. fileEa->NextOffset = 0;
  50. fileEa->Flags = 0;
  51. fileEa->EaNameLength = WS2IFSL_PROCESS_EA_NAME_LENGTH;
  52. fileEa->EaValueLength = 0;
  53. strcpy (fileEa->EaName, WS2IFSL_PROCESS_EA_NAME);
  54. status = NtCreateFile (&ProcessFile,
  55. FILE_ALL_ACCESS,
  56. fileAttr,
  57. &ioStatus,
  58. NULL, // Allocation size
  59. FILE_ATTRIBUTE_NORMAL,
  60. 0, // ShareAccess
  61. FILE_OPEN_IF, // Create disposition
  62. 0, // Create options
  63. fullEaBuffer,
  64. sizeof (fullEaBuffer));
  65. if (NT_SUCCESS (status)) {
  66. printf ("Created process file, handle: %lx.\n", ProcessFile);
  67. ApcThreadHdl = CreateThread (NULL,
  68. 0,
  69. ApcThread,
  70. hEvent,
  71. 0,
  72. &apcThreadId);
  73. if (ApcThreadHdl!=NULL) {
  74. rc = WaitForSingleObject (hEvent, INFINITE);
  75. if (rc==WAIT_OBJECT_0) {
  76. HANDLE socketFile;
  77. HANDLE hCompletion;
  78. char TestBuffer[sizeof (TestString)];
  79. DWORD count, key;
  80. OVERLAPPED readOVLP, writeOVLP, ctrlOVLP;
  81. POVERLAPPED ovlp;
  82. WS2IFSL_SOCKET_CTX socketCtx;
  83. fileEa = (PPFILE_FULL_EA_INFORMATION)fullEaBuffer;
  84. fileEa->NextOffset = 0;
  85. fileEa->Flags = 0;
  86. fileEa->EaNameLength = WS2IFSL_SOCKET_EA_NAME_LENGTH;
  87. fileEa->EaValueLength = 0;
  88. strcpy (fileEa->EaName, WS2IFSL_SOCKET_EA_NAME);
  89. status = NtCreateFile (&socketFile,
  90. FILE_ALL_ACCESS,
  91. fileAttr,
  92. &ioStatus,
  93. NULL, // Allocation size
  94. FILE_ATTRIBUTE_NORMAL,
  95. 0, // ShareAccess
  96. FILE_OPEN_IF, // Create disposition
  97. 0, // Create options
  98. fullEaBuffer,
  99. sizeof (fullEaBuffer));
  100. if (NT_SUCCESS (status)) {
  101. printf ("Created socket file, handle:%lx\n", socketFile);
  102. socketCtx.SocketCtx = socketFile;
  103. socketCtx.ProcessFile = ProcessFile;
  104. res = DeviceIoControl (socketFile,
  105. IOCTL_WS2IFSL_SET_SOCKET_CONTEXT,
  106. &socketCtx,
  107. sizeof (socketCtx),
  108. NULL,
  109. 0,
  110. &count,
  111. NULL);
  112. if (res) {
  113. hCompletion = CreateIoCompletionPort (socketFile,
  114. NULL,
  115. 1,
  116. 0);
  117. if (hCompletion!=NULL) {
  118. memset (TestBuffer, 0, sizeof (TestBuffer));
  119. readOVLP.hEvent = NULL;
  120. res = ReadFile (socketFile,
  121. TestBuffer,
  122. sizeof (TestBuffer),
  123. &count,
  124. &readOVLP);
  125. if (res || (GetLastError ()==ERROR_IO_PENDING)) {
  126. writeOVLP.hEvent = NULL;
  127. res = WriteFile (socketFile,
  128. TestString,
  129. sizeof (TestString),
  130. &count,
  131. &writeOVLP);
  132. if (res || (GetLastError ()==ERROR_IO_PENDING)) {
  133. ctrlOVLP.Internal = STATUS_BUFFER_OVERFLOW;
  134. ctrlOVLP.InternalHigh = 10;
  135. ctrlOVLP.hEvent = NULL;
  136. res = DeviceIoControl (socketFile,
  137. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  138. &ctrlOVLP,
  139. sizeof (IO_STATUS_BLOCK),
  140. NULL,
  141. 0,
  142. &count,
  143. NULL);
  144. do {
  145. res = GetQueuedCompletionStatus (hCompletion,
  146. &count,
  147. &key,
  148. &ovlp,
  149. INFINITE);
  150. if (ovlp!=NULL) {
  151. if (ovlp==&readOVLP) {
  152. printf ("Read completed,"
  153. "key: %ld, error: %ld, count: %ld, string: %ls.\n",
  154. key,
  155. res ? 0 : GetLastError (),
  156. count,
  157. TestBuffer);
  158. done |= 1;
  159. }
  160. else if (ovlp==&writeOVLP) {
  161. printf ("Write completed,"
  162. "key:%ld, error: %ld, count: %ld.\n",
  163. key,
  164. res ? 0 : GetLastError (),
  165. count);
  166. done |= 2;
  167. }
  168. else if (ovlp==&ctrlOVLP) {
  169. printf ("Control completed,"
  170. "key:%ld, error: %ld, count: %ld.\n",
  171. key,
  172. res ? 0 : GetLastError (),
  173. count);
  174. done |= 4;
  175. }
  176. }
  177. else {
  178. prinf ("GetQueuedCompletionStatus failed, error %ld.\n",
  179. GetLastError ());
  180. break;
  181. }
  182. }
  183. while (done!=7);
  184. }
  185. else {
  186. printf ("Write failed, error: %ld.\n", GetLastError ());
  187. }
  188. }
  189. else {
  190. printf ("Read failed, error: %ld.\n", GetLastError ());
  191. }
  192. CloseHandle (hCompletion);
  193. }
  194. else {
  195. printf ("Could not create completion port, error %ld.\n",
  196. GetLastError ());
  197. }
  198. }
  199. else {
  200. printf ("IOCTL_WS2IFSL_SET_SOCKET_CONTEXT failed, error: %ld.\n",
  201. GetLastError ());
  202. }
  203. NtClose (socketFile);
  204. }
  205. else {
  206. printf ("Could not create socket file, status:%lx\n", status);
  207. }
  208. }
  209. else {
  210. printf ("Wait for event failed, rc=%lx, error=%ld.\n",
  211. rc, GetLastError ());
  212. }
  213. QueueUserAPC (ExitThreadApc, ApcThreadHdl, 0);
  214. WaitForSingleObject (ApcThreadHdl, INFINITE);
  215. CloseHandle (ApcThreadHdl);
  216. }
  217. else {
  218. printf ("Could not create thread.\n");
  219. }
  220. NtClose (ProcessFile);
  221. }
  222. CloseHandle (hEvent);
  223. }
  224. DWORD WINAPI
  225. ApcThread (
  226. PVOID param
  227. ) {
  228. WS2IFSL_APC_REQUEST ApcRequest;
  229. WS2IFSL_THREAD_CTX threadCtx;
  230. HANDLE hEvent = (HANDLE)param;
  231. BOOL res;
  232. OVERLAPPED ovlp;
  233. threadCtx.ApcThreadHdl = ApcThreadHdl;
  234. threadCtx.ApcRoutine = Ws2ifslApc;
  235. ovlp.hEvent = NULL;
  236. res = DeviceIoControl (socketFile,
  237. IOCTL_WS2IFSL_SET_THREAD_CONTEXT,
  238. &threadCtx,
  239. sizeof (threadCtx),
  240. &ApcRequest,
  241. sizeof (ApcRequest),
  242. &count,
  243. &ovlp);
  244. SetEvent (hEvent);
  245. if (!res && (GetLastError ()==ERROR_IO_PEDNING) {
  246. printf ("ApcThread: going into sleep mode....\n");
  247. while (TRUE)
  248. SleepEx (INIFINITE, TRUE);
  249. }
  250. else
  251. printf ("IOCTL_WS2IFSL_SET_THREAD_CONTEXT returned: %ld (status: %lx).\n",
  252. res ? 0 : GetLastError (), ovlp.Internal);
  253. return 0;
  254. }
  255. VOID CALLBACK
  256. ExitThreadApc (
  257. DWORD param
  258. ) {
  259. ExitThread (param);
  260. }
  261. typedef struct _PENDING_REQUEST {
  262. HANDLE SocketCtx;
  263. PVOID RequestCtx;
  264. PVOID Buffer;
  265. ULONG Length;
  266. } PENDING_REQUEST, *PPENDING_REQUEST;
  267. PPENDING_REQUEST ReadRequest, WriteRequest;
  268. VOID
  269. Ws2ifslApc (
  270. IN PWS2IFSL_APC_REQUEST Request,
  271. IN PVOID RequestCtx,
  272. IN PVOID SocketCtx
  273. ) {
  274. IO_STATUS_BLOCK IoStatus;
  275. DWORD count;
  276. switch (Request->request) {
  277. case WS2IFSL_APC_REQUEST_READ:
  278. printf ("Processing read request, buffer: %lx, length: %ld, request %lx, context:%lx.",
  279. Request->Read.Buffer,
  280. Request->Read.Length,
  281. RequestCtx,
  282. SocketCtx);
  283. if (WriteRequest!=NULL) {
  284. if (WriteRequest->Length<=Request->Read.Length) {
  285. memcpy (Request->Read.Buffer, WriteRequest.Buffer, WriteRequest.Length);
  286. IoStatus.Status = STATUS_SUCCESS;
  287. IoStatus.Information = WriteRequest.Length;
  288. }
  289. else {
  290. memcpy (Request->Read.Buffer, WriteRequest.Buffer, Request.Read.Length);
  291. IoStatus.Status = STATUS_BUFFER_OVERFLOW;
  292. IoStatus.Information = Request.Read.Length;
  293. }
  294. res = DeviceIoControl ((HANDLE)WriteRequest->SocketCtx,
  295. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  296. &IoStatus,
  297. sizeof (IoStatus),
  298. WriteRequest->RequestCtx,
  299. 0,
  300. &count,
  301. NULL);
  302. if (res)
  303. printf ("Completed write request, buffer %lx, count %ld, status %lx.\n",
  304. WriteRequest->Buffer, IoStatus.Information, IoStatus.Status);
  305. else
  306. printf ("IOCTL_WS2IFSL_COMPLETE_REQUEST failed, error %ld\n", GetLastError ());
  307. free (WriteRequest);
  308. WriteRequest = NULL;
  309. }
  310. else if (ReadRequest==NULL) {
  311. ReadRequest = (PPENDING_REQUEST)malloc (sizeof (PENDING_REQUEST));
  312. if (ReadRequest!=NULL) {
  313. ReadRequest->SocketCtx = SocketCtx;
  314. ReadRequest->RequestCtx = RequestCtx;
  315. ReadRequest->Buffer = Request->Read.Buffer;
  316. ReadRequest->Length = Request->Read.Length;
  317. printf ("Pended read request.\n");
  318. break;
  319. }
  320. else {
  321. IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  322. IoStatus.Information = 0;
  323. }
  324. }
  325. else {
  326. IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  327. IoStatus.Information = 0;
  328. }
  329. res = DeviceIoControl ((HANDLE)SocketCtx,
  330. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  331. &IoStatus,
  332. sizeof (IoStatus),
  333. RequestCtx,
  334. 0,
  335. &count,
  336. NULL);
  337. if (res)
  338. printf ("Completed read request, buffer %lx, count %ld, status %lx.\n",
  339. Request->Read.Buffer, IoStatus.Information, IoStatus.Status);
  340. else
  341. printf ("IOCTL_WS2IFSL_COMPLETE_REQUEST failed, error %ld\n", GetLastError ());
  342. break;
  343. case WS2IFSL_APC_REQUEST_WRITE:
  344. printf ("Processing write request, buffer: %lx, length: %ld, request %lx, context:%lx.",
  345. Request->Write.Buffer,
  346. Request->Write.Length,
  347. RequestCtx,
  348. SocketCtx);
  349. if (ReadRequest!=NULL) {
  350. if (ReadRequest->Length>=Request->Write.Length) {
  351. memcpy (ReadRequest->Buffer, Request->Write.Buffer, Request->Write.Length);
  352. IoStatus.Status = STATUS_SUCCESS;
  353. IoStatus.Information = Request->Write.Length;
  354. }
  355. else {
  356. memcpy (ReadRequest->Buffer, Request->Write.Buffer, ReadRequest->Length);
  357. IoStatus.Status = STATUS_BUFFER_OVERFLOW;
  358. IoStatus.Information = ReadRequest->Length;
  359. }
  360. res = DeviceIoControl ((HANDLE)ReadRequest->SocketCtx,
  361. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  362. &IoStatus,
  363. sizeof (IoStatus),
  364. ReadRequest->RequestCtx,
  365. 0,
  366. &count,
  367. NULL);
  368. if (res)
  369. printf ("Completed read request, buffer %lx, count %ld, status %lx.\n",
  370. ReadRequest->Buffer, IoStatus.Information, IoStatus.Status);
  371. else
  372. printf ("IOCTL_WS2IFSL_COMPLETE_REQUEST failed, error %ld\n", GetLastError ());
  373. free (ReadRequest);
  374. ReadRequest = NULL;
  375. }
  376. else if (WriteRequest==NULL) {
  377. WriteRequest = (PPENDING_REQUEST)malloc (sizeof (PENDING_REQUEST));
  378. if (WriteRequest!=NULL) {
  379. WriteRequest->SocketCtx = SocketCtx;
  380. WriteRequest->RequestCtx = RequestCtx;
  381. WriteRequest->Buffer = Request->Write.Buffer;
  382. WriteRequest->Length = Request->Write.Length;
  383. printf ("Pended write request.\n");
  384. break;
  385. }
  386. else {
  387. IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  388. IoStatus.Information = 0;
  389. }
  390. }
  391. else {
  392. IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  393. IoStatus.Information = 0;
  394. }
  395. res = DeviceIoControl ((HANDLE)SocketCtx,
  396. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  397. &IoStatus,
  398. sizeof (IoStatus),
  399. RequestCtx,
  400. 0,
  401. &count,
  402. NULL);
  403. if (res)
  404. printf ("Completed write request, buffer %lx, count %ld, status %lx.\n",
  405. Request->Read.Buffer, IoStatus.Information, IoStatus.Status);
  406. else
  407. printf ("IOCTL_WS2IFSL_COMPLETE_REQUEST failed, error %ld\n", GetLastError ());
  408. break;
  409. case WS2IFSL_APC_REQUEST_CLOSE:
  410. printf ("Processing close request: %lx, context:%lx.",
  411. RequestCtx,
  412. SocketCtx);
  413. if ((WriteRequest!=NULL) && (WriteRequest->RequestCtx==RequestCtx)) {
  414. IoStatus.Status = STATUS_CANCELLED;
  415. IoStatus.Information = 0;
  416. res = DeviceIoControl ((HANDLE)WriteRequest->SocketCtx,
  417. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  418. &IoStatus,
  419. sizeof (IoStatus),
  420. WriteRequest->RequestCtx,
  421. 0,
  422. &count,
  423. NULL);
  424. if (res)
  425. printf ("Completed write request, buffer %lx, count %ld, status %lx.\n",
  426. WriteRequest->Buffer, IoStatus.Information, IoStatus.Status);
  427. else
  428. printf ("IOCTL_WS2IFSL_COMPLETE_REQUEST failed, error %ld\n", GetLastError ());
  429. }
  430. if ((ReadRequest!=NULL) && (ReadRequest->RequestCtx==RequestCtx)) {
  431. IoStatus.Status = STATUS_CANCELLED;
  432. IoStatus.Information = 0;
  433. res = DeviceIoControl ((HANDLE)ReadRequest->SocketCtx,
  434. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  435. &IoStatus,
  436. sizeof (IoStatus),
  437. ReadRequest->RequestCtx,
  438. 0,
  439. &count,
  440. NULL);
  441. if (res)
  442. printf ("Completed read request, buffer %lx, count %ld, status %lx.\n",
  443. ReadRequest->Buffer, IoStatus.Information, IoStatus.Status);
  444. else
  445. printf ("IOCTL_WS2IFSL_COMPLETE_REQUEST failed, error %ld\n", GetLastError ());
  446. }
  447. IoStatus.Status = STATUS_SUCCESS;
  448. IoStatus.Information = 0;
  449. res = DeviceIoControl ((HANDLE)SocketCtx,
  450. IOCTL_WS2IFSL_COMPLETE_REQUEST,
  451. &IoStatus,
  452. sizeof (IoStatus),
  453. RequestCtx,
  454. 0,
  455. &count,
  456. NULL);
  457. if (res)
  458. printf ("Completed close request, status %lx.\n", IoStatus.Status);
  459. else
  460. printf ("IOCTL_WS2IFSL_COMPLETE_REQUEST failed, error %ld\n", GetLastError ());
  461. break;
  462. default:
  463. break;
  464. }
  465. }