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);
64 /****** rpc security kernel functions ******/
65 /* before making an upcall from kernel code, set the security context by
66 * passing the access_token to rpc_set_context. remove the context after all
67 * upcalls are done. the rpc library automatically checks and sets this
68 * same context on the other end. */
70 struct rpc_cred_map_entry
77 struct rpc_cred_map_entry cred_map[MAX_CRED_MAPS];
78 rpc_t *rpc_list_head = NULL;
81 rpc_set_context(void *context)
86 thd = PsGetCurrentThread();
91 for (x = 0; x < MAX_CRED_MAPS; x++)
93 if (cred_map[x].thread == NULL)
95 if (cred_map[x].thread == thd)
97 //////FIX///ASSERT(cred_map[x].token == context);
99 //cred_map[x].token = context;
105 cred_map[empty].thread = thd;
106 cred_map[empty].token = context;
107 cred_map[empty].refs = 1;
117 void *rpc_get_context()
122 thd = PsGetCurrentThread();
125 for (x = 0; x < MAX_CRED_MAPS; x++)
126 if (cred_map[x].thread == thd)
127 return cred_map[x].token;
137 thd = PsGetCurrentThread();
139 for (x = 0; x < MAX_CRED_MAPS; x++)
140 if (cred_map[x].thread == thd)
142 if (cred_map[x].refs > 1)
148 cred_map[x].token = NULL;
149 cred_map[x].thread = NULL;
161 /* rpc stubs in kernel */
163 rpc_t *rpc_create(int size_hint)
167 SECURITY_SUBJECT_CONTEXT subj_context;
168 PACCESS_TOKEN acc_token;
170 LARGE_INTEGER user_id;
174 /* get user's identification from auth token*/
175 token = rpc_get_context();
177 status = SeQueryAuthenticationIdToken(token, &auth_id);
179 user_id.LowPart = auth_id.LowPart;
180 user_id.HighPart = auth_id.HighPart;
184 if (!(rpc = rpc_upgrade(NULL, 0, 1)))
186 size = sizeof(rpc_t) + 2*RPC_BUF_SIZE;
187 rpc = ExAllocatePoolWithTag(NonPagedPool, size, 0x1234);
191 memset(rpc, 0, size);
192 rpc->next = rpc_list_head;
194 rpc_upgrade(rpc, 0, 1);
197 rpc->out_buf = rpc->out_pos = (char*)(rpc+1);
198 rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+RPC_BUF_SIZE;
200 rpc->key = rand() + 10;
201 rpc_marshal_long(rpc, rpc->key);
202 rpc->bulk_out_len = (ULONG*)rpc->out_pos;
203 rpc_marshal_long(rpc, 0);
206 /* another way of obtaining credentials, with different effects */
207 SeCaptureSubjectContext(&subj_context);
208 acc_token = SeQuerySubjectContextToken(&subj_context);
209 status = SeQueryAuthenticationIdToken(acc_token, &auth_id);
211 user_id.LowPart = auth_id.LowPart;
212 user_id.HighPart = auth_id.HighPart;
213 SeReleaseSubjectContext(&subj_context);
216 rpc_marshal_longlong(rpc, user_id);
223 void rpc_destroy(rpc_t *rpc)
230 if (rpc_upgrade(rpc, -1, 0))
238 /* rpc internal functions for usermode */
240 rpc_t *rpc_create(int size_hint)
246 size = sizeof(rpc_t) + 2*RPC_BUF_SIZE;
249 osi_panic("ifs_rpc: alloc buffer", __FILE__, __LINE__);
250 memset(rpc, 0, size);
252 rpc->out_buf = rpc->out_pos = (char*)(rpc+1);
253 rpc->in_buf = rpc->in_pos = ((char*)(rpc+1)) + RPC_BUF_SIZE;
255 rpc->key = rand() + 10;
256 rpc_marshal_long(rpc, rpc->key);
261 void rpc_destroy(rpc_t *rpc)
269 rpc_transact(rpc_t *rpc)
277 return IFSL_GENERIC_FAILURE;
279 header_len = rpc->out_pos - rpc->out_buf;
282 return ifs_TransactRpc(rpc->out_buf, header_len, rpc->in_buf, &read);
289 uc_namei(WCHAR *name, ULONG *fid)
295 /* consider putting namei cache here */
301 rpc_marshal_long(rpc, RPC_NAMEI);
302 rpc_marshal_long(rpc, wcslen(name));
304 rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0);
306 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
309 rpt0(("cancel", "cancel namei"));
310 return IFSL_RPC_TIMEOUT;
313 rpc_unmarshal_long(rpc, &status);
314 rpc_unmarshal_long(rpc, fid);
320 uc_check_access(ULONG fid, ULONG access, ULONG *granted)
329 rpc_marshal_long(rpc, RPC_CHECK_ACCESS);
330 rpc_marshal_long(rpc, fid);
331 rpc_marshal_long(rpc, access);
334 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
337 rpt0(("cancel", "cancel access"));
338 return IFSL_RPC_TIMEOUT;
341 rpc_unmarshal_long(rpc, &status);
342 rpc_unmarshal_long(rpc, granted);
348 uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid)
357 rpc_marshal_long(rpc, RPC_CREATE);
358 rpc_marshal_long(rpc, attribs);
359 rpc_marshal_longlong(rpc, alloc);
360 rpc_marshal_long(rpc, access);
362 rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0);
363 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
366 rpt0(("cancel", "cancel create"));
367 return IFSL_RPC_TIMEOUT;
370 rpc_unmarshal_long(rpc, &status);
371 rpc_unmarshal_long(rpc, granted);
372 rpc_unmarshal_long(rpc, fid);
378 uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written)
387 rpc_marshal_long(rpc, RPC_STAT);
388 rpc_marshal_long(rpc, fid);
391 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
394 rpt0(("cancel", "cancel stat"));
395 return IFSL_RPC_TIMEOUT;
398 rpc_unmarshal_long(rpc, &status);
399 rpc_unmarshal_long(rpc, attribs);
400 rpc_unmarshal_longlong(rpc, size);
401 rpc_unmarshal_longlong(rpc, creation);
402 rpc_unmarshal_longlong(rpc, access);
403 rpc_unmarshal_longlong(rpc, change);
404 rpc_unmarshal_longlong(rpc, written);
410 uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written)
419 rpc_marshal_long(rpc, RPC_SETINFO);
420 rpc_marshal_long(rpc, fid);
421 rpc_marshal_long(rpc, attribs);
422 rpc_marshal_longlong(rpc, creation);
423 rpc_marshal_longlong(rpc, access);
424 rpc_marshal_longlong(rpc, change);
425 rpc_marshal_longlong(rpc, written);
429 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
432 rpt0(("cancel", "cancel setinfo"));
433 return IFSL_RPC_TIMEOUT;
436 rpc_unmarshal_long(rpc, &status);
442 uc_trunc(ULONG fid, LARGE_INTEGER size)
451 rpc_marshal_long(rpc, RPC_TRUNC);
452 rpc_marshal_long(rpc, fid);
453 rpc_marshal_longlong(rpc, size);
456 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
459 rpt0(("cancel", "cancel trunc"));
460 return IFSL_RPC_TIMEOUT;
463 rpc_unmarshal_long(rpc, &status);
469 uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data)
478 rpc_marshal_long(rpc, RPC_READ);
479 rpc_marshal_long(rpc, fid);
480 rpc_marshal_longlong(rpc, offset);
481 rpc_marshal_long(rpc, length);
483 rpc_queue_bulk(rpc, NULL, 0, data, length);
484 if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
487 rpt0(("cancel", "cancel read"));
488 return IFSL_RPC_TIMEOUT;
491 rpc_unmarshal_long(rpc, &status);
492 rpc_unmarshal_long(rpc, read);
498 uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data)
507 rpc_marshal_long(rpc, RPC_WRITE);
508 rpc_marshal_long(rpc, fid);
509 rpc_marshal_longlong(rpc, offset);
510 rpc_marshal_long(rpc, length);
512 rpc_queue_bulk(rpc, data, length, NULL, 0);
513 if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
516 rpt0(("cancel", "cancel write"));
517 return IFSL_RPC_TIMEOUT;
520 rpc_unmarshal_long(rpc, &status);
521 rpc_unmarshal_long(rpc, written);
527 uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG *len)
536 rpc_marshal_long(rpc, RPC_READDIR);
537 rpc_marshal_long(rpc, fid);
538 rpc_marshal_longlong(rpc, cookie_in);
539 rpc_marshal_wstr(rpc, filter);
540 rpc_marshal_long(rpc, *len);
542 rpc_queue_bulk(rpc, NULL, 0, data, *len);
543 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
546 rpt0(("cancel", "cancel readdir"));
547 return IFSL_RPC_TIMEOUT;
550 rpc_unmarshal_long(rpc, &status);
551 rpc_unmarshal_long(rpc, count);
552 rpc_unmarshal_long(rpc, len);
567 rpc_marshal_long(rpc, RPC_CLOSE);
568 rpc_marshal_long(rpc, fid);
571 if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
574 rpt0(("cancel", "cancel close"));
575 return IFSL_RPC_TIMEOUT;
578 rpc_unmarshal_long(rpc, &status);
584 uc_unlink(WCHAR *name)
593 rpc_marshal_long(rpc, RPC_UNLINK);
594 rpc_marshal_wstr(rpc, name);
597 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
600 rpt0(("cancel", "cancel unlink"));
601 return IFSL_RPC_TIMEOUT;
604 rpc_unmarshal_long(rpc, &status);
610 uc_ioctl_write(ULONG length, char *data, ULONG *key)
619 rpc_marshal_long(rpc, RPC_IOCTL_WRITE);
620 rpc_marshal_long(rpc, length);
622 rpc_queue_bulk(rpc, data, length, NULL, 0);
623 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
626 rpt0(("cancel", "cancel ioctl write"));
627 return IFSL_RPC_TIMEOUT;
630 rpc_unmarshal_long(rpc, &status);
631 rpc_unmarshal_long(rpc, key);
637 uc_ioctl_read(ULONG key, ULONG *length, char *data)
646 rpc_marshal_long(rpc, RPC_IOCTL_READ);
647 rpc_marshal_long(rpc, key);
649 rpc_queue_bulk(rpc, NULL, 0, data, *length);
650 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
653 rpt0(("cancel", "cancel ioctl read"));
654 return IFSL_RPC_TIMEOUT;
657 rpc_unmarshal_long(rpc, &status);
658 rpc_unmarshal_long(rpc, length);
664 uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid)
673 rpc_marshal_long(rpc, RPC_RENAME);
674 rpc_marshal_long(rpc, fid);
675 rpc_marshal_wstr(rpc, curr);
676 rpc_marshal_wstr(rpc, new_dir);
677 rpc_marshal_wstr(rpc, new_name);
680 if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT))
683 rpt0(("cancel", "cancel rename"));
684 return IFSL_RPC_TIMEOUT;
687 rpc_unmarshal_long(rpc, &status);
688 rpc_unmarshal_long(rpc, new_fid);
703 rpc_marshal_long(rpc, RPC_FLUSH);
704 rpc_marshal_long(rpc, fid);
707 if (!rpc_wait(rpc, RPC_TIMEOUT_LONG))
710 rpt0(("cancel", "cancel flush"));
711 return IFSL_RPC_TIMEOUT;
714 rpc_unmarshal_long(rpc, &status);
724 dc_break_callback(ULONG fid)
733 rpc_marshal_long(rpc, RPC_BREAK_CALLBACK);
734 rpc_marshal_long(rpc, fid);
735 if (!rpc_transact(rpc))
738 return IFSL_GENERIC_FAILURE;
740 rpc_unmarshal_long(rpc, &status);
754 rpc_marshal_long(rpc, RPC_RELEASE_HOOKS);
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 /* dead rpc structs should not be returned */
828 if (curr->key == id && curr->status != 0)
835 rpc_t *rpc_upgrade(rpc_t *rpc, int old_status, int new_status)
841 ASSERT(!old_status || rpc_find(rpc->key));
842 if (old_status != -1 && rpc->status != old_status)
848 curr = rpc_list_head;
851 if (old_status == -1 || curr->status == old_status)
860 ASSERT(old_status == -1 || curr->status == old_status);
861 curr->status = new_status;
866 rpc_queue(rpc_t *rpc)
872 KeInitializeEvent(&rpc->ev, NotificationEvent, FALSE);
873 ret = (rpc_upgrade(rpc, 1, 2) != NULL);
874 KeSetEvent(&comExt->outEvent, 0, FALSE);
881 rpc_cancel(rpc_t *rpc)
892 curr = rpc_list_head;
896 ExFreePoolWithTag(curr, 0x1234);
900 rpc_list_head = NULL;
905 rpc_wait(rpc_t *rpc, BOOLEAN long_op)
908 LARGE_INTEGER timeout;
911 timeout.QuadPart = -600000000L; /* 60 seconds 60L*10000000L */
913 timeout.QuadPart = -200000000L; /* 20 seconds 20L*10000000L */
916 ret = KeWaitForSingleObject(&rpc->ev, Executive, KernelMode, FALSE, &timeout);
917 while (ret != STATUS_SUCCESS && ret != STATUS_TIMEOUT);
920 if (rpc->status == 2 || /* still queued */
921 rpc->status == 5) /* send cancelled by library */
928 if (ret == STATUS_SUCCESS)
933 rpc_queue_bulk(rpc_t *rpc, char *out_bulk, ULONG out_len, char *in_bulk, ULONG in_len)
935 rpc->bulk_out = out_bulk;
936 *rpc->bulk_out_len = out_len;
937 rpc->bulk_in = in_bulk;
938 rpc->bulk_in_max = in_len;
939 return rpc_queue(rpc);
942 rpc_get_len(rpc_t *rpc)
944 if (*rpc->bulk_out_len != 0xFFFFFFFC)
945 return rpc->out_pos - rpc->out_buf + *rpc->bulk_out_len + sizeof(ULONG);
947 return rpc->out_pos - rpc->out_buf + sizeof(ULONG);
950 rpc_send(char *out_buf, int out_len, int *out_written)
959 rpc = rpc_upgrade(NULL, 2, 3);
967 if (rpc_get_len(rpc) > out_len)
970 rpt0(("cancel", "cancel on send"));
971 rpc_upgrade(rpc, -1, 5);
972 KeSetEvent(&rpc->ev, IO_NETWORK_INCREMENT, FALSE);
976 header_len = rpc->out_pos - rpc->out_buf;
977 RtlCopyMemory(out_buf, rpc->out_buf, header_len);
979 if (*rpc->bulk_out_len && rpc->bulk_out)
980 RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len);
981 *out_written = header_len + *rpc->bulk_out_len;
984 return (*out_written != 0);
989 /* rpc library api */
991 rpc_recv(char *in_buf, ULONG len)
993 ULONG key, header_size;
999 rpc = rpc_find(*(ULONG*)in_buf);
1000 if (!rpc) /* rpc was cancelled while waiting */
1006 alloc = rpc->in_buf;
1007 rpc->in_buf = rpc->in_pos = in_buf;
1008 rpc_unmarshal_long(rpc, &key);
1009 ASSERT(key == rpc->key);
1010 rpc_unmarshal_long(rpc, &rpc->bulk_in_len);
1012 rpc->in_buf = rpc->in_pos = alloc;
1013 header_size = len - rpc->bulk_in_len;
1014 ASSERT(header_size < RPC_BUF_SIZE);
1016 RtlCopyMemory(rpc->in_buf, in_buf + 2*sizeof(ULONG), header_size - 2*sizeof(ULONG));
1017 if (rpc->bulk_in_len && rpc->bulk_in)
1019 ASSERT(rpc->bulk_in_len <= rpc->bulk_in_max);
1020 RtlCopyMemory(rpc->bulk_in, in_buf + header_size, rpc->bulk_in_len);
1023 KeSetEvent(&rpc->ev, IO_NETWORK_INCREMENT, FALSE); /* priority boost for waiting thread */
1028 rpc_call(ULONG in_len, char *in_buf, ULONG out_max, char *out_buf, ULONG *out_len)
1034 LARGE_INTEGER user_id;
1037 rpc.in_buf = rpc.in_pos = in_buf;
1038 rpc.out_buf = rpc.out_pos = out_buf;
1040 rpc_unmarshal_long(&rpc, &key);
1041 rpc_unmarshal_long(&rpc, &rpc_code);
1045 case RPC_BREAK_CALLBACK:
1046 rpc_unmarshal_long(&rpc, &fid);
1047 status = dc_break_callback(fid);
1048 rpc_marshal_long(&rpc, status);
1050 case RPC_RELEASE_HOOKS:
1051 status = dc_release_hooks();
1054 *out_len = rpc.out_pos - rpc.out_buf;
1060 rpc_parse(rpc_t *rpc)
1066 LARGE_INTEGER user_id;
1068 rpc_unmarshal_long(rpc, &key);
1069 rpc_unmarshal_long(rpc, &rpc->bulk_in_len);
1070 rpc_unmarshal_longlong(rpc, &user_id);
1071 rpc_unmarshal_long(rpc, &rpc_code);
1073 ifs_ImpersonateClient(user_id);
1075 rpc_marshal_long(rpc, key);
1076 rpc->bulk_out_len = (ULONG*)rpc->out_pos;
1077 rpc_marshal_long(rpc, 0);
1085 //rpc_unmarshal_wstr(rpc, name);
1086 rpc_unmarshal_long(rpc, &length);
1087 //data = *((char**)rpc->in_pos);
1089 status = uc_namei((WCHAR*)data, &fid);
1090 //status = uc_namei(name, &fid);
1091 rpc_marshal_long(rpc, status);
1092 rpc_marshal_long(rpc, fid);
1095 case RPC_CHECK_ACCESS:
1097 ULONG fid, access, granted;
1098 rpc_unmarshal_long(rpc, &fid);
1099 rpc_unmarshal_long(rpc, &access);
1100 status = uc_check_access(fid, access, &granted);
1101 rpc_marshal_long(rpc, status);
1102 rpc_marshal_long(rpc, granted);
1107 LARGE_INTEGER alloc;
1108 ULONG access, granted, fid, attribs;
1111 rpc_unmarshal_long(rpc, &attribs);
1112 rpc_unmarshal_longlong(rpc, &alloc);
1113 rpc_unmarshal_long(rpc, &access);
1114 //rpc_unmarshal_wstr(rpc, name);
1116 status = uc_create((WCHAR*)data, attribs, alloc, access, &granted, &fid);
1117 rpc_marshal_long(rpc, status);
1118 rpc_marshal_long(rpc, granted);
1119 rpc_marshal_long(rpc, fid);
1125 LARGE_INTEGER size, creation, access, change, written;
1126 rpc_unmarshal_long(rpc, &fid);
1127 status = uc_stat(fid, &attribs, &size, &creation, &access, &change, &written);
1128 rpc_marshal_long(rpc, status);
1129 rpc_marshal_long(rpc, attribs);
1130 rpc_marshal_longlong(rpc, size);
1131 rpc_marshal_longlong(rpc, creation);
1132 rpc_marshal_longlong(rpc, access);
1133 rpc_marshal_longlong(rpc, change);
1134 rpc_marshal_longlong(rpc, written);
1139 ULONG fid, length, read;
1140 LARGE_INTEGER offset;
1142 rpc_unmarshal_long(rpc, &fid);
1143 rpc_unmarshal_longlong(rpc, &offset);
1144 rpc_unmarshal_long(rpc, &length);
1145 save = rpc->out_pos;
1146 rpc_marshal_long(rpc, 0);
1147 rpc_marshal_long(rpc, 0);
1148 data = rpc->out_pos;
1149 rpc->out_pos = save;
1150 status = uc_read(fid, offset, length, &read, data);
1151 rpc_marshal_long(rpc, status);
1152 rpc_marshal_long(rpc, read);
1153 rpc->out_pos += read;
1154 *rpc->bulk_out_len = read;
1159 ULONG fid, length, written;
1160 LARGE_INTEGER offset;
1162 rpc_unmarshal_long(rpc, &fid);
1163 rpc_unmarshal_longlong(rpc, &offset);
1164 rpc_unmarshal_long(rpc, &length);
1166 status = uc_write(fid, offset, length, &written, data);
1167 rpc_marshal_long(rpc, status);
1168 rpc_marshal_long(rpc, written);
1175 rpc_unmarshal_long(rpc, &fid);
1176 rpc_unmarshal_longlong(rpc, &size);
1177 status = uc_trunc(fid, size);
1178 rpc_marshal_long(rpc, status);
1184 LARGE_INTEGER creation, access, change, written;
1185 rpc_unmarshal_long(rpc, &fid);
1186 rpc_unmarshal_long(rpc, &attribs);
1187 rpc_unmarshal_longlong(rpc, &creation);
1188 rpc_unmarshal_longlong(rpc, &access);
1189 rpc_unmarshal_longlong(rpc, &change);
1190 rpc_unmarshal_longlong(rpc, &written);
1191 status = uc_setinfo(fid, attribs, creation, access, change, written);
1192 rpc_marshal_long(rpc, status);
1197 ULONG fid, count, len;
1198 LARGE_INTEGER cookie_in;
1200 rpc_unmarshal_long(rpc, &fid);
1201 rpc_unmarshal_longlong(rpc, &cookie_in);
1202 rpc_unmarshal_wstr(rpc, name);
1203 rpc_unmarshal_long(rpc, &len);
1204 save = rpc->out_pos;
1205 rpc_marshal_long(rpc, 0);
1206 rpc_marshal_long(rpc, 0);
1207 rpc_marshal_long(rpc, 0);
1208 data = rpc->out_pos;
1209 rpc->out_pos = save;
1210 status = uc_readdir(fid, cookie_in, name, &count, data, &len);
1211 rpc_marshal_long(rpc, status);
1212 rpc_marshal_long(rpc, count);
1213 rpc_marshal_long(rpc, len);
1214 rpc->out_pos += len;
1215 *rpc->bulk_out_len = len;
1221 rpc_unmarshal_long(rpc, &fid);
1222 status = uc_close(fid);
1223 rpc_marshal_long(rpc, status);
1229 rpc_unmarshal_wstr(rpc, name);
1230 status = uc_unlink(name);
1231 rpc_marshal_long(rpc, status);
1234 case RPC_IOCTL_WRITE:
1237 rpc_unmarshal_long(rpc, &length);
1238 status = uc_ioctl_write(length, rpc->in_pos, &key);
1239 rpc_marshal_long(rpc, status);
1240 rpc_marshal_long(rpc, key);
1243 case RPC_IOCTL_READ:
1247 rpc_unmarshal_long(rpc, &key);
1248 save = rpc->out_pos;
1249 rpc_marshal_long(rpc, 0);
1250 rpc_marshal_long(rpc, 0);
1251 data = rpc->out_pos;
1252 rpc->out_pos = save;
1253 status = uc_ioctl_read(key, &length, data);
1254 rpc_marshal_long(rpc, status);
1255 rpc_marshal_long(rpc, length);
1256 rpc->out_pos += length;
1257 *rpc->bulk_out_len = length;
1263 WCHAR curr[1024], new_dir[1024], new_name[1024];
1264 rpc_unmarshal_long(rpc, &fid);
1265 rpc_unmarshal_wstr(rpc, curr);
1266 rpc_unmarshal_wstr(rpc, new_dir);
1267 rpc_unmarshal_wstr(rpc, new_name);
1268 status = uc_rename(fid, curr, new_dir, new_name, &new_fid);
1269 rpc_marshal_long(rpc, status);
1270 rpc_marshal_long(rpc, new_fid);
1276 rpc_unmarshal_long(rpc, &fid);
1277 status = uc_flush(fid);
1278 rpc_marshal_long(rpc, status);