2 * the regents of the university of michigan
5 * permission is granted to use, copy, create derivative works and
6 * redistribute this software and such derivative works for any purpose,
7 * so long as the name of the university of michigan is not used in
8 * any advertising or publicity pertaining to the use or distribution
9 * of this software without specific, written prior authorization. if
10 * the above copyright notice or any other identification of the
11 * university of michigan is included in any copy of any portion of
12 * this software, then the disclaimer below must also be included.
14 * this software is provided as is, without representation from the
15 * university of michigan as to its fitness for any purpose, and without
16 * warranty by the university of michigan of any kind, either express
17 * or implied, including without limitation the implied warranties of
18 * merchantability and fitness for a particular purpose. the regents
19 * of the university of michigan shall not be liable for any damages,
20 * including special, indirect, incidental, or consequential damages,
21 * with respect to any claim arising out or in connection with the use
22 * of the software, even if it has been or is hereafter advised of the
23 * possibility of such damages.
28 * 03-jun 2005 (eric williams) entered into versioning
40 /* general internal functions */
41 rpc_t *rpc_create(int size_hint);
42 void rpc_destroy(rpc_t *rpc);
43 int rpc_marshal_long(rpc_t *rpc, ULONG data);
44 int rpc_marshal_longlong(rpc_t *rpc, LARGE_INTEGER data);
45 int rpc_marshal_wstr(rpc_t *rpc, WCHAR *str);
46 int rpc_unmarshal_long(rpc_t *rpc, ULONG *data);
47 int rpc_unmarshal_longlong(rpc_t *rpc, LARGE_INTEGER *data);
48 int rpc_unmarshal_wstr(rpc_t *rpc, WCHAR *str);
50 /* kernel-queue specific internal functions */
52 int rpc_queue(rpc_t *rpc);
53 rpc_queue_bulk(rpc_t *rpc, char *out_bulk, ULONG out_len, char *in_bulk, ULONG in_len);
54 rpc_cancel(rpc_t *rpc);
55 rpc_send_reg(rpc_t *rpc, char *out_buf);
56 rpc_queue_bulk_mdl(rpc_t *rpc, MDL *mdl);
57 rpc_t *rpc_find(int id);
58 rpc_t *rpc_upgrade(rpc_t *rpc, int old_status, int new_status);
59 rpc_wait(rpc_t *rpc, BOOLEAN long_op);
60 rpc_send_mdl(rpc_t *rpc, char *out_buf);
63 /* internal timing functions (not used) */
65 #define TIMING_START() LARGE_INTEGER start, stop; \
66 start.QuadPart = KeQueryInterruptTime();
67 #define TIMING_END(name) stop.QuadPart = KeQueryInterruptTime(); \
68 rpt5((name, "%s %d", name, (ULONG)(stop.QuadPart - start.QuadPart)));
72 /* rpc security kernel functions */
74 struct rpc_cred_map_entry
80 struct rpc_cred_map_entry cred_map[20];
81 rpc_t *rpc_list_head = NULL;
83 rpc_set_context(void *context)
88 thd = PsGetCurrentThread();
93 for (x = 0; x < 20; x++)
95 if (cred_map[x].thread == NULL)
97 if (cred_map[x].thread == thd)
99 cred_map[x].token = context;
105 cred_map[empty].thread = thd;
106 cred_map[empty].token = context;
116 void *rpc_get_context()
121 thd = PsGetCurrentThread();
124 for (x = 0; x < 20; x++)
125 if (cred_map[x].thread == thd)
126 return cred_map[x].token;
136 thd = PsGetCurrentThread();
138 for (x = 0; x < 20; x++)
139 if (cred_map[x].thread == thd)
141 cred_map[x].token = NULL;
142 cred_map[x].thread = NULL;
152 /* rpc internal functions for kernel */
154 rpc_t *rpc_create(int size_hint)
158 SECURITY_SUBJECT_CONTEXT subj_context;
159 PACCESS_TOKEN acc_token;
161 LARGE_INTEGER user_id;
165 token = rpc_get_context();
167 status = SeQueryAuthenticationIdToken(token, &auth_id);
169 user_id.LowPart = auth_id.LowPart;
170 user_id.HighPart = auth_id.HighPart;
174 if (!(rpc = rpc_upgrade(NULL, 0, 1)))
176 size = sizeof(rpc_t) + 4096*10;
177 rpc = ExAllocatePoolWithTag(NonPagedPool, size, 0x1234);
180 memset(rpc, 0, size);
181 rpc->next = rpc_list_head;
183 rpc_upgrade(rpc, 0, 1);
186 rpc->out_buf = rpc->out_pos = (char*)(rpc+1);
187 rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+2048*10;
189 rpc->key = rand() + 10;
190 rpc_marshal_long(rpc, rpc->key);
191 rpc->bulk_out_len = (ULONG*)rpc->out_pos;
192 rpc_marshal_long(rpc, 0);
194 /*SeCaptureSubjectContext(&subj_context);
195 acc_token = SeQuerySubjectContextToken(&subj_context);
196 status = SeQueryAuthenticationIdToken(acc_token, &auth_id);*/
197 /**token = rpc_get_context();
199 status = SeQueryAuthenticationIdToken(token, &auth_id);
201 user_id.LowPart = auth_id.LowPart;
202 user_id.HighPart = auth_id.HighPart;
203 SeReleaseSubjectContext(&subj_context);*/
205 rpc_marshal_longlong(rpc, user_id);
212 void rpc_destroy(rpc_t *rpc)
217 /*ExFreePoolWithTag(rpc, 0x1234);*/
220 if (rpc_upgrade(rpc, -1, 0))
228 /* rpc internal functions for usermode */
230 rpc_t *rpc_create(int size_hint)
236 size = sizeof(rpc_t) + 4096;
240 memset(rpc, 0, size);
242 rpc->out_buf = rpc->out_pos = (char*)(rpc+1);
243 rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+2048;
245 rpc->key = rand() + 10;
246 rpc_marshal_long(rpc, rpc->key);
251 void rpc_destroy(rpc_t *rpc)
260 rpc_transact(rpc_t *rpc)
268 return IFSL_GENERIC_FAILURE;
270 header_len = rpc->out_pos - rpc->out_buf;
273 return ifs_TransactRpc(rpc->out_buf, header_len, rpc->in_buf, &read);
280 uc_namei(WCHAR *name, ULONG *fid)
286 /* put namei cache here */
290 rpc_marshal_long(rpc, RPC_NAMEI);
291 rpc_marshal_long(rpc, wcslen(name));
293 rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0);
295 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
298 rpt0(("cancel", "cancel namei"));
299 return IFSL_RPC_TIMEOUT;
302 rpc_unmarshal_long(rpc, &status);
303 rpc_unmarshal_long(rpc, fid);
310 uc_check_access(ULONG fid, ULONG access, ULONG *granted)
318 rpc_marshal_long(rpc, RPC_CHECK_ACCESS);
319 rpc_marshal_long(rpc, fid);
320 rpc_marshal_long(rpc, access);
323 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
326 rpt0(("cancel", "cancel access"));
327 return IFSL_RPC_TIMEOUT;
330 rpc_unmarshal_long(rpc, &status);
331 rpc_unmarshal_long(rpc, granted);
334 TIMING_END("access");
338 uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid)
346 rpc_marshal_long(rpc, RPC_CREATE);
347 rpc_marshal_long(rpc, attribs);
348 rpc_marshal_longlong(rpc, alloc);
349 rpc_marshal_long(rpc, access);
351 rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0);
352 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
355 rpt0(("cancel", "cancel create"));
356 return IFSL_RPC_TIMEOUT;
359 rpc_unmarshal_long(rpc, &status);
360 rpc_unmarshal_long(rpc, granted);
361 rpc_unmarshal_long(rpc, fid);
364 TIMING_END("create");
368 uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written)
376 rpc_marshal_long(rpc, RPC_STAT);
377 rpc_marshal_long(rpc, fid);
380 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
383 rpt0(("cancel", "cancel stat"));
384 return IFSL_RPC_TIMEOUT;
387 rpc_unmarshal_long(rpc, &status);
388 rpc_unmarshal_long(rpc, attribs);
389 rpc_unmarshal_longlong(rpc, size);
390 rpc_unmarshal_longlong(rpc, creation);
391 rpc_unmarshal_longlong(rpc, access);
392 rpc_unmarshal_longlong(rpc, change);
393 rpc_unmarshal_longlong(rpc, written);
400 uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written)
408 rpc_marshal_long(rpc, RPC_SETINFO);
409 rpc_marshal_long(rpc, fid);
410 rpc_marshal_long(rpc, attribs);
411 rpc_marshal_longlong(rpc, creation);
412 rpc_marshal_longlong(rpc, access);
413 rpc_marshal_longlong(rpc, change);
414 rpc_marshal_longlong(rpc, written);
418 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
421 rpt0(("cancel", "cancel setinfo"));
422 return IFSL_RPC_TIMEOUT;
425 rpc_unmarshal_long(rpc, &status);
428 TIMING_END("setinfo");
432 uc_trunc(ULONG fid, LARGE_INTEGER size)
440 rpc_marshal_long(rpc, RPC_TRUNC);
441 rpc_marshal_long(rpc, fid);
442 rpc_marshal_longlong(rpc, size);
445 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
448 rpt0(("cancel", "cancel trunc"));
449 return IFSL_RPC_TIMEOUT;
452 rpc_unmarshal_long(rpc, &status);
459 uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data)
467 rpc_marshal_long(rpc, RPC_READ);
468 rpc_marshal_long(rpc, fid);
469 rpc_marshal_longlong(rpc, offset);
470 rpc_marshal_long(rpc, length);
472 rpc_queue_bulk(rpc, NULL, 0, data, length);
473 if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
476 rpt0(("cancel", "cancel read"));
477 return IFSL_RPC_TIMEOUT;
480 rpc_unmarshal_long(rpc, &status);
481 rpc_unmarshal_long(rpc, read);
488 /*uc_read_mdl(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, MDL *data)
496 rpc_marshal_long(rpc, RPC_READ_BULK);
497 rpc_marshal_long(rpc, fid);
498 rpc_marshal_longlong(rpc, offset);
499 rpc_marshal_long(rpc, length);
501 rpc_queue_bulk_mdl(rpc, data);
502 if (!rpc_wait(rpc, 1))
505 rpt0(("cancel", "cancel read mdl"));
506 return IFSL_RPC_TIMEOUT;
509 rpc_unmarshal_long(rpc, &status);
510 rpc_unmarshal_long(rpc, read);
513 TIMING_END("read_mdl");
517 uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data)
525 rpc_marshal_long(rpc, RPC_WRITE);
526 rpc_marshal_long(rpc, fid);
527 rpc_marshal_longlong(rpc, offset);
528 rpc_marshal_long(rpc, length);
530 rpc_queue_bulk(rpc, data, length, NULL, 0);
531 if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
534 rpt0(("cancel", "cancel write"));
535 return IFSL_RPC_TIMEOUT;
538 rpc_unmarshal_long(rpc, &status);
539 rpc_unmarshal_long(rpc, written);
546 /*uc_write_mdl(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, MDL *data)
554 rpc_marshal_long(rpc, RPC_WRITE_BULK);
555 rpc_marshal_long(rpc, fid);
556 rpc_marshal_longlong(rpc, offset);
557 rpc_marshal_long(rpc, length);
559 rpc_queue_bulk_mdl(rpc, data);
560 if (!rpc_wait(rpc, 1))
563 rpt0(("cancel", "cancel write mdl"));
564 return IFSL_RPC_TIMEOUT;
567 rpc_unmarshal_long(rpc, &status);
568 rpc_unmarshal_long(rpc, written);
571 TIMING_END("write_mdl");
575 uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG *len)
583 rpc_marshal_long(rpc, RPC_READDIR);
584 rpc_marshal_long(rpc, fid);
585 rpc_marshal_longlong(rpc, cookie_in);
586 rpc_marshal_wstr(rpc, filter);
587 rpc_marshal_long(rpc, *len);
589 rpc_queue_bulk(rpc, NULL, 0, data, *len);
590 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
593 rpt0(("cancel", "cancel readdir"));
594 return IFSL_RPC_TIMEOUT;
597 rpc_unmarshal_long(rpc, &status);
598 rpc_unmarshal_long(rpc, count);
599 rpc_unmarshal_long(rpc, len);
602 TIMING_END("readdir");
614 rpc_marshal_long(rpc, RPC_CLOSE);
615 rpc_marshal_long(rpc, fid);
618 if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
621 rpt0(("cancel", "cancel close"));
622 return IFSL_RPC_TIMEOUT;
625 rpc_unmarshal_long(rpc, &status);
632 uc_unlink(WCHAR *name)
640 rpc_marshal_long(rpc, RPC_UNLINK);
641 rpc_marshal_wstr(rpc, name);
644 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
647 rpt0(("cancel", "cancel unlink"));
648 return IFSL_RPC_TIMEOUT;
651 rpc_unmarshal_long(rpc, &status);
654 TIMING_END("unlink");
658 uc_ioctl_write(ULONG length, char *data, ULONG *key)
666 rpc_marshal_long(rpc, RPC_IOCTL_WRITE);
667 rpc_marshal_long(rpc, length);
669 rpc_queue_bulk(rpc, data, length, NULL, 0);
670 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
673 rpt0(("cancel", "cancel ioctl write"));
674 return IFSL_RPC_TIMEOUT;
677 rpc_unmarshal_long(rpc, &status);
678 rpc_unmarshal_long(rpc, key);
681 TIMING_END("ioctl_write");
685 uc_ioctl_read(ULONG key, ULONG *length, char *data)
693 rpc_marshal_long(rpc, RPC_IOCTL_READ);
694 rpc_marshal_long(rpc, key);
696 rpc_queue_bulk(rpc, NULL, 0, data, *length);
697 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
700 rpt0(("cancel", "cancel ioctl read"));
701 return IFSL_RPC_TIMEOUT;
704 rpc_unmarshal_long(rpc, &status);
705 rpc_unmarshal_long(rpc, length);
708 TIMING_END("ioctl_read");
712 uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid)
720 rpc_marshal_long(rpc, RPC_RENAME);
721 rpc_marshal_long(rpc, fid);
722 rpc_marshal_wstr(rpc, curr);
723 rpc_marshal_wstr(rpc, new_dir);
724 rpc_marshal_wstr(rpc, new_name);
727 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
730 rpt0(("cancel", "cancel rename"));
731 return IFSL_RPC_TIMEOUT;
734 rpc_unmarshal_long(rpc, &status);
735 rpc_unmarshal_long(rpc, new_fid);
738 TIMING_END("rename");
746 dc_break_callback(ULONG fid)
753 rpc_marshal_long(rpc, RPC_BREAK_CALLBACK);
754 rpc_marshal_long(rpc, fid);
755 if (!rpc_transact(rpc))
758 return IFSL_GENERIC_FAILURE;
760 rpc_unmarshal_long(rpc, &status);
767 /* rpc packing function */
768 rpc_marshal_long(rpc_t *rpc, ULONG data)
770 memcpy(rpc->out_pos, &data, sizeof(ULONG));
771 rpc->out_pos += sizeof(ULONG);
775 rpc_marshal_longlong(rpc_t *rpc, LARGE_INTEGER data)
777 memcpy(rpc->out_pos, &data, sizeof(LARGE_INTEGER));
778 rpc->out_pos += sizeof(LARGE_INTEGER);
782 rpc_marshal_wstr(rpc_t *rpc, WCHAR *str)
786 rpc_marshal_long(rpc, len);
787 memcpy(rpc->out_pos, str, len*sizeof(WCHAR));
788 rpc->out_pos += len*sizeof(WCHAR);
793 rpc_unmarshal_long(rpc_t *rpc, ULONG *data)
795 memcpy(data, rpc->in_pos, sizeof(ULONG));
796 rpc->in_pos += sizeof(ULONG);
800 rpc_unmarshal_longlong(rpc_t *rpc, LARGE_INTEGER *data)
802 memcpy(data, rpc->in_pos, sizeof(LARGE_INTEGER));
803 rpc->in_pos += sizeof(LARGE_INTEGER);
807 rpc_unmarshal_wstr(rpc_t *rpc, WCHAR *str)//, int len)
810 rpc_unmarshal_long(rpc, &len);
811 memcpy(str, rpc->in_pos, len*sizeof(WCHAR));
812 rpc->in_pos += len*sizeof(WCHAR);
818 /* kernel-queue management functions */
820 rpc_t *rpc_find(int id)
824 curr = rpc_list_head;
827 if (curr->key == id && curr->status != 0)
834 rpc_t *rpc_upgrade(rpc_t *rpc, int old_status, int new_status)
840 ASSERT(!old_status || rpc_find(rpc->key));
841 if (old_status != -1 && rpc->status != old_status)
847 curr = rpc_list_head;
850 if (old_status == -1 || curr->status == old_status)
859 ASSERT(old_status == -1 || curr->status == old_status);
860 curr->status = new_status;
865 rpc_queue(rpc_t *rpc)
871 KeInitializeEvent(&rpc->ev, NotificationEvent, FALSE);
872 ret = (rpc_upgrade(rpc, 1, 2) != NULL);
873 KeSetEvent(&comExt->outEvent, 0, FALSE);
880 rpc_cancel(rpc_t *rpc)
883 //ExAcquireFastMutex(&ext->inLock);
885 if (rpc_upgrade(rpc, -1, 0))
888 //RtlDeleteElementGenericTable(&ext->inTable, (void*)&rpc);
889 //ExReleaseFastMutex(&ext->inLock);
898 curr = rpc_list_head;
902 ExFreePoolWithTag(curr, 0x1234);
905 rpc_list_head = NULL;
910 rpc_wait(rpc_t *rpc, BOOLEAN long_op)
913 LARGE_INTEGER timeout;
914 //p->FsContext = (ULONG)&ev;
917 timeout.QuadPart = -600000000L; /* 60 seconds 60L*1000000L */
919 timeout.QuadPart = -200000000L; /* 20 seconds 20L*1000000L */
922 ret = KeWaitForSingleObject(&rpc->ev, Executive, KernelMode, FALSE, &timeout);
923 while (ret != STATUS_SUCCESS);// && ret != STATUS_TIMEOUT);
925 /*if (KeReadStateEvent(&rpc->ev) == 0)
927 if (rpc->status == 5)
930 if (ret == STATUS_SUCCESS)
936 rpc_queue_bulk(rpc_t *rpc, char *out_bulk, ULONG out_len, char *in_bulk, ULONG in_len)
938 rpc->bulk_out = out_bulk;
939 *rpc->bulk_out_len = out_len;
940 rpc->bulk_in = in_bulk;
941 rpc->bulk_in_max = in_len;
942 return rpc_queue(rpc);
945 /*rpc_queue_bulk_mdl(rpc_t *rpc, MDL *bulk)
947 rpc->bulk_mdl = bulk;
948 *rpc->bulk_out_len = 0xFFFFFFFC;
950 return rpc_queue(rpc);
953 rpc_get_len(rpc_t *rpc)
955 if (*rpc->bulk_out_len != 0xFFFFFFFC)
956 return rpc->out_pos - rpc->out_buf + *rpc->bulk_out_len + sizeof(ULONG);
958 return rpc->out_pos - rpc->out_buf + sizeof(ULONG);
961 rpc_send(char *out_buf, int out_len, int *out_written)
970 rpc = rpc_upgrade(NULL, 2, 3);
978 if (rpc_get_len(rpc) > out_len)
982 rpt0(("cancel", "cancel on send"));
983 rpc_upgrade(rpc, -1, 5);
984 KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE); /* move to rpc_ fn */
986 goto restart;//return 0;
991 /*mdl = (*rpc->bulk_out_len == 0xFFFFFFFC);
994 *rpc->bulk_out_len = 0;*/
996 header_len = rpc->out_pos - rpc->out_buf;
997 RtlCopyMemory(out_buf, rpc->out_buf, header_len);
1001 if (*rpc->bulk_out_len && rpc->bulk_out)
1002 RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len);
1003 *out_written = header_len + *rpc->bulk_out_len;
1016 MmProbeAndLockPages(rpc->bulk_mdl, UserMode, IoModifyAccess);
1018 except (EXCEPTION_EXECUTE_HANDLER)
1025 rpc->bulk_out = MmMapLockedPagesSpecifyCache(rpc->bulk_mdl, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority);
1027 except (EXCEPTION_EXECUTE_HANDLER)
1032 ptr = ExAllocatePool(PagedPool, MmGetMdlByteCount(rpc->bulk_mdl));
1033 remap = IoAllocateMdl(ptr, MmGetMdlByteCount(rpc->bulk_mdl), FALSE, TRUE, NULL);
1034 MmProbeAndLockPages(remap, UserMode, IoModifyAccess);
1035 rpc->bulk_out = MmMapLockedPagesSpecifyCache(remap, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority);
1037 rpc->bulk_out = MmGetSystemAddressForMdlSafe(rpc->bulk_mdl, NormalPagePriority);
1038 MmUnmapLockedPages(rpc->bulk_out, rpc->bulk_mdl);
1039 rpc->bulk_out = MmMapLockedPagesSpecifyCache(rpc->bulk_mdl, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority);
1041 remap = IoAllocateMdl(rpc->bulk_out, MmGetMdlByteCount(rpc->bulk_mdl), FALSE, TRUE, NULL);
1042 remap->Process = (void*)PsGetCurrentProcess();
1043 MmBuildMdlForNonPagedPool(remap);
1044 //MmProbeAndLockPages(remap, UserMode, IoModifyAccess);
1045 rpc->bulk_out = MmMapLockedPagesSpecifyCache(remap, UserMode, MmNonCached, (void*)0x01111111, FALSE, NormalPagePriority);
1046 /*ifs_unlock_rpcs();
1047 rpc_upgrade(rpc, -1, 5);
1048 KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE);
1050 goto restart;//return 0;*/
1052 ptr = rpc->bulk_out;
1053 RtlCopyMemory(out_buf + header_len, &ptr, sizeof(ptr));
1056 *rpc->bulk_out_len = 0xFFFFFFFC;
1057 *out_written = header_len + sizeof(void*);
1062 return (*out_written != 0);
1066 rpc_send_reg(rpc_t *rpc, char *out_buf)
1070 header_len = rpc->out_pos - rpc->out_buf;
1071 RtlCopyMemory(out_buf, rpc->out_buf, header_len);
1073 if (rpc->bulk_out_len && rpc->bulk_out)
1074 RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len);
1075 return header_len + *rpc->bulk_out_len;
1081 /* rpc library api */
1083 rpc_recv(char *in_buf, ULONG len)
1085 ULONG key, header_size;
1091 rpc = rpc_find(*(ULONG*)in_buf);
1100 /*if (*rpc->bulk_out_len == 0xFFFFFFFC)
1102 ASSERT(rpc->bulk_out);
1103 MmUnmapLockedPages(rpc->bulk_out, rpc->bulk_mdl);
1104 // MmUnlockPages(rpc->bulk_mdl);
1107 alloc = rpc->in_buf;
1108 rpc->in_buf = rpc->in_pos = in_buf;
1109 rpc_unmarshal_long(rpc, &key);
1110 ASSERT(key == rpc->key);
1111 rpc_unmarshal_long(rpc, &rpc->bulk_in_len);
1113 rpc->in_buf = rpc->in_pos = alloc;
1114 header_size = len - rpc->bulk_in_len;
1115 ASSERT(header_size < 4096);
1116 RtlCopyMemory(rpc->in_buf, in_buf + 2*sizeof(ULONG), header_size - 2*sizeof(ULONG));
1117 //if (*rpc->bulk_out_len != 0xFFFFFFFC)
1119 if (rpc->bulk_in_len && rpc->bulk_in)
1121 ASSERT(rpc->bulk_in_len <= rpc->bulk_in_max);
1123 RtlCopyMemory(rpc->bulk_in, in_buf + header_size, rpc->bulk_in_len);//len - header_size - 2*sizeof(ULONG));
1127 KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE);
1132 rpc_call(ULONG in_len, char *in_buf, ULONG out_max, char *out_buf, ULONG *out_len)
1138 LARGE_INTEGER user_id;
1141 rpc.in_buf = rpc.in_pos = in_buf;
1142 rpc.out_buf = rpc.out_pos = out_buf;
1144 rpc_unmarshal_long(&rpc, &key);
1145 rpc_unmarshal_long(&rpc, &rpc_code);
1149 case RPC_BREAK_CALLBACK:
1150 rpc_unmarshal_long(&rpc, &fid);
1151 status = dc_break_callback(fid);
1152 rpc_marshal_long(&rpc, status);
1155 *out_len = rpc.out_pos - rpc.out_buf;
1157 //ifs_ImpersonateClient(user_id);
1162 rpc_parse(rpc_t *rpc)
1168 LARGE_INTEGER user_id;
1170 rpc_unmarshal_long(rpc, &key);
1171 rpc_unmarshal_long(rpc, &rpc->bulk_in_len);
1172 rpc_unmarshal_longlong(rpc, &user_id);
1173 rpc_unmarshal_long(rpc, &rpc_code);
1175 ifs_ImpersonateClient(user_id);
1177 rpc_marshal_long(rpc, key);
1178 rpc->bulk_out_len = (ULONG*)rpc->out_pos;
1179 rpc_marshal_long(rpc, 0);
1187 //rpc_unmarshal_wstr(rpc, name);
1188 rpc_unmarshal_long(rpc, &length);
1189 //data = *((char**)rpc->in_pos);
1191 status = uc_namei((WCHAR*)data, &fid);
1192 //status = uc_namei(name, &fid);
1193 rpc_marshal_long(rpc, status);
1194 rpc_marshal_long(rpc, fid);
1197 case RPC_CHECK_ACCESS:
1199 ULONG fid, access, granted;
1200 rpc_unmarshal_long(rpc, &fid);
1201 rpc_unmarshal_long(rpc, &access);
1202 status = uc_check_access(fid, access, &granted);
1203 rpc_marshal_long(rpc, status);
1204 rpc_marshal_long(rpc, granted);
1209 LARGE_INTEGER alloc;
1210 ULONG access, granted, fid, attribs;
1213 rpc_unmarshal_long(rpc, &attribs);
1214 rpc_unmarshal_longlong(rpc, &alloc);
1215 rpc_unmarshal_long(rpc, &access);
1216 //rpc_unmarshal_wstr(rpc, name);
1218 status = uc_create((WCHAR*)data, attribs, alloc, access, &granted, &fid);
1219 rpc_marshal_long(rpc, status);
1220 rpc_marshal_long(rpc, granted);
1221 rpc_marshal_long(rpc, fid);
1227 LARGE_INTEGER size, creation, access, change, written;
1228 rpc_unmarshal_long(rpc, &fid);
1229 status = uc_stat(fid, &attribs, &size, &creation, &access, &change, &written);
1230 rpc_marshal_long(rpc, status);
1231 rpc_marshal_long(rpc, attribs);
1232 rpc_marshal_longlong(rpc, size);
1233 rpc_marshal_longlong(rpc, creation);
1234 rpc_marshal_longlong(rpc, access);
1235 rpc_marshal_longlong(rpc, change);
1236 rpc_marshal_longlong(rpc, written);
1241 ULONG fid, length, read;
1242 LARGE_INTEGER offset;
1244 rpc_unmarshal_long(rpc, &fid);
1245 rpc_unmarshal_longlong(rpc, &offset);
1246 rpc_unmarshal_long(rpc, &length);
1247 save = rpc->out_pos;
1248 rpc_marshal_long(rpc, 0);
1249 rpc_marshal_long(rpc, 0);
1250 data = rpc->out_pos;
1251 rpc->out_pos = save;
1252 status = uc_read(fid, offset, length, &read, data);
1253 rpc_marshal_long(rpc, status);
1254 rpc_marshal_long(rpc, read);
1255 rpc->out_pos += read;
1256 *rpc->bulk_out_len = read;
1259 /* case RPC_READ_BULK:
1261 ULONG fid, length, read;
1262 LARGE_INTEGER offset;
1264 rpc_unmarshal_long(rpc, &fid);
1265 rpc_unmarshal_longlong(rpc, &offset);
1266 rpc_unmarshal_long(rpc, &length);
1267 data = *((char**)rpc->in_pos);
1268 status = uc_read(fid, offset, length, &read, data);
1269 rpc_marshal_long(rpc, status);
1270 rpc_marshal_long(rpc, read);
1271 *rpc->bulk_out_len = 0;
1276 ULONG fid, length, written;
1277 LARGE_INTEGER offset;
1279 rpc_unmarshal_long(rpc, &fid);
1280 rpc_unmarshal_longlong(rpc, &offset);
1281 rpc_unmarshal_long(rpc, &length);
1283 status = uc_write(fid, offset, length, &written, data);
1284 rpc_marshal_long(rpc, status);
1285 rpc_marshal_long(rpc, written);
1288 /* case RPC_WRITE_BULK:
1290 ULONG fid, length, written;
1291 LARGE_INTEGER offset;
1294 rpc_unmarshal_long(rpc, &fid);
1295 rpc_unmarshal_longlong(rpc, &offset);
1296 rpc_unmarshal_long(rpc, &length);
1297 data = *((char**)rpc->in_pos);
1298 status = uc_write(fid, offset, length, &written, data);
1299 rpc_marshal_long(rpc, status);
1300 rpc_marshal_long(rpc, written);
1307 rpc_unmarshal_long(rpc, &fid);
1308 rpc_unmarshal_longlong(rpc, &size);
1309 status = uc_trunc(fid, size);
1310 rpc_marshal_long(rpc, status);
1316 LARGE_INTEGER creation, access, change, written;
1317 rpc_unmarshal_long(rpc, &fid);
1318 rpc_unmarshal_long(rpc, &attribs);
1319 rpc_unmarshal_longlong(rpc, &creation);
1320 rpc_unmarshal_longlong(rpc, &access);
1321 rpc_unmarshal_longlong(rpc, &change);
1322 rpc_unmarshal_longlong(rpc, &written);
1323 status = uc_setinfo(fid, attribs, creation, access, change, written);
1324 rpc_marshal_long(rpc, status);
1329 ULONG fid, count, len;
1330 LARGE_INTEGER cookie_in;
1332 rpc_unmarshal_long(rpc, &fid);
1333 rpc_unmarshal_longlong(rpc, &cookie_in);
1334 rpc_unmarshal_wstr(rpc, name);
1335 rpc_unmarshal_long(rpc, &len);
1336 save = rpc->out_pos;
1337 rpc_marshal_long(rpc, 0);
1338 rpc_marshal_long(rpc, 0);
1339 rpc_marshal_long(rpc, 0);
1340 data = rpc->out_pos;
1341 rpc->out_pos = save;
1342 status = uc_readdir(fid, cookie_in, name, &count, data, &len);
1343 rpc_marshal_long(rpc, status);
1344 rpc_marshal_long(rpc, count);
1345 rpc_marshal_long(rpc, len);
1346 rpc->out_pos += len;
1347 *rpc->bulk_out_len = len;
1353 rpc_unmarshal_long(rpc, &fid);
1354 status = uc_close(fid);
1355 rpc_marshal_long(rpc, status);
1361 rpc_unmarshal_wstr(rpc, name);
1362 status = uc_unlink(name);
1363 rpc_marshal_long(rpc, status);
1366 case RPC_IOCTL_WRITE:
1369 rpc_unmarshal_long(rpc, &length);
1370 status = uc_ioctl_write(length, rpc->in_pos, &key);
1371 rpc_marshal_long(rpc, status);
1372 rpc_marshal_long(rpc, key);
1375 case RPC_IOCTL_READ:
1379 rpc_unmarshal_long(rpc, &key);
1380 save = rpc->out_pos;
1381 rpc_marshal_long(rpc, 0);
1382 rpc_marshal_long(rpc, 0);
1383 data = rpc->out_pos;
1384 rpc->out_pos = save;
1385 status = uc_ioctl_read(key, &length, data);
1386 rpc_marshal_long(rpc, status);
1387 rpc_marshal_long(rpc, length);
1388 rpc->out_pos += length;
1389 *rpc->bulk_out_len = length;
1395 WCHAR curr[1024], new_dir[1024], new_name[1024];
1396 rpc_unmarshal_long(rpc, &fid);
1397 rpc_unmarshal_wstr(rpc, curr);
1398 rpc_unmarshal_wstr(rpc, new_dir);
1399 rpc_unmarshal_wstr(rpc, new_name);
1400 status = uc_rename(fid, curr, new_dir, new_name, &new_fid);
1401 rpc_marshal_long(rpc, status);
1402 rpc_marshal_long(rpc, new_fid);