16 static inline void assert_server_locked(
struct ncp_server *server)
18 if (server->
lock == 0) {
19 DPRINTK(
"ncpfs: server not locked!\n");
25 assert_server_locked(server);
33 assert_server_locked(server);
41 assert_server_locked(server);
48 assert_server_locked(server);
56 assert_server_locked(server);
61 static inline void ncp_add_dword_lh(
struct ncp_server *server,
__u32 x) {
67 assert_server_locked(server);
73 static void ncp_add_pstring(
struct ncp_server *server,
const char *
s)
76 assert_server_locked(server);
78 DPRINTK(
"ncpfs: string too long: %s\n", s);
81 ncp_add_byte(server, len);
82 ncp_add_mem(server, s, len);
86 static inline void ncp_init_request(
struct ncp_server *server)
94 static inline void ncp_init_request_s(
struct ncp_server *server,
int subfunction)
99 ncp_add_byte(server, subfunction);
112 return *(
const u8 *)data;
117 return *(
const u8 *)ncp_reply_data(server, offset);
120 static inline u16 WVAL_LH(
const void *
data)
122 return get_unaligned_le16(data);
126 ncp_reply_le16(
struct ncp_server *server,
int offset)
128 return get_unaligned_le16(ncp_reply_data(server, offset));
132 ncp_reply_be16(
struct ncp_server *server,
int offset)
134 return get_unaligned_be16(ncp_reply_data(server, offset));
137 static inline u32 DVAL_LH(
const void *
data)
143 ncp_reply_dword(
struct ncp_server *server,
int offset)
148 static inline __u32 ncp_reply_dword_lh(
struct ncp_server* server,
int offset) {
149 return le32_to_cpu(ncp_reply_dword(server, offset));
157 ncp_init_request(server);
158 ncp_add_be16(server, size);
160 if ((result = ncp_request(server, 33)) != 0) {
164 *target =
min_t(
unsigned int, ncp_reply_be16(server, 0), size);
177 int size,
int options,
int *ret_size,
int *ret_options) {
183 ncp_init_request(server);
184 ncp_add_be16(server, size);
185 ncp_add_byte(server, options);
187 if ((result = ncp_request(server, 0x61)) != 0)
194 result = ncp_reply_be16(server, 0);
196 size =
min(result, size);
198 *ret_options = ncp_reply_byte(server, 4);
209 ncp_init_request_s(server, 44);
210 ncp_add_byte(server, n);
212 if ((result = ncp_request(server, 22)) != 0) {
216 target->
free_blocks = ncp_reply_dword_lh(server, 4);
226 len = ncp_reply_byte(server, 29);
228 DPRINTK(
"ncpfs: volume name too long: %d\n", len);
243 ncp_init_request_s(server, 45);
244 ncp_add_byte(server, n);
246 if ((result = ncp_request(server, 22)) != 0) {
250 target->
free_blocks = ncp_reply_dword_lh(server, 4);
260 len = ncp_reply_byte(server, 21);
262 DPRINTK(
"ncpfs: volume name too long: %d\n", len);
277 ncp_init_request(server);
278 ncp_add_byte(server, 0);
279 ncp_add_mem(server, file_id, 6);
281 result = ncp_request(server, 66);
298 PPRINTK(
"ncp_make_closed: volnum=%d, dirent=%u, error=%d\n",
306 static void ncp_add_handle_path(
struct ncp_server *server,
__u8 vol_num,
307 __le32 dir_base,
int have_dir_base,
310 ncp_add_byte(server, vol_num);
311 ncp_add_dword(server, dir_base);
312 if (have_dir_base != 0) {
313 ncp_add_byte(server, 1);
315 ncp_add_byte(server, 0xff);
318 ncp_add_byte(server, 1);
319 ncp_add_pstring(server, path);
321 ncp_add_byte(server, 0);
329 ncp_init_request(server);
330 ncp_add_byte(server, 12);
332 ncp_add_byte(server, 0);
333 ncp_add_word(server, 0);
334 ncp_add_handle_path(server, volnum, dirent, 1,
NULL);
335 if ((result = ncp_request(server, 87)) == 0) {
336 *dirhandle = ncp_reply_byte(server, 0);
345 ncp_init_request_s(server, 20);
346 ncp_add_byte(server, dirhandle);
347 result = ncp_request(server, 22);
357 memcpy(target, structure, info_struct_size);
358 name_len = structure + info_struct_size;
366 #ifdef CONFIG_NCPFS_NFS_NS
367 static inline void ncp_extract_nfs_info(
const unsigned char *structure,
370 target->
mode = DVAL_LH(structure);
371 target->
rdev = DVAL_LH(structure + 8);
380 #ifdef CONFIG_NCPFS_NFS_NS
383 if (ncp_is_nfs_extras(server, volnum)) {
384 ncp_init_request(server);
385 ncp_add_byte(server, 19);
386 ncp_add_byte(server, server->
name_space[volnum]);
388 ncp_add_byte(server, 0);
389 ncp_add_byte(server, volnum);
390 ncp_add_dword(server, target->
dirEntNum);
395 if ((result = ncp_request(server, 87)) == 0) {
396 ncp_extract_nfs_info(ncp_reply_data(server, 0), &target->nfs);
398 "ncp_obtain_nfs_info: (%s) mode=0%o, rdev=0x%x\n",
402 target->nfs.mode = 0;
403 target->nfs.rdev = 0;
410 target->nfs.mode = 0;
411 target->nfs.rdev = 0;
423 __u8 volnum = NCP_FINFO(dir)->volNumber;
427 if (target ==
NULL) {
431 ncp_init_request(server);
432 ncp_add_byte(server, 6);
433 ncp_add_byte(server, server->
name_space[volnum]);
434 ncp_add_byte(server, server->
name_space[volnum]);
436 ncp_add_dword(server,
RIM_ALL);
437 ncp_add_handle_path(server, volnum, dirent, 1, path);
439 if ((result = ncp_request(server, 87)) != 0)
452 #ifdef CONFIG_NCPFS_NFS_NS
454 ncp_obtain_DOS_dir_base(
struct ncp_server *server,
461 ncp_init_request(server);
462 ncp_add_byte(server, 6);
463 ncp_add_byte(server, ns);
464 ncp_add_byte(server, ns);
467 ncp_add_handle_path(server, volnum, dirent, 1, path);
469 if ((result = ncp_request(server, 87)) == 0)
471 if (DOS_dir_base) *DOS_dir_base=ncp_reply_dword(server, 0x34);
481 #if defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS)
486 ncp_init_request(server);
487 ncp_add_byte(server, 24);
488 ncp_add_word(server, 0);
489 ncp_add_byte(server, volume);
491 if ((result = ncp_request(server, 87)) != 0) {
497 no_namespaces = ncp_reply_le16(server, 0);
498 namespace = ncp_reply_data(server, 2);
500 while (no_namespaces > 0) {
501 DPRINTK(
"get_namespaces: found %d on %d\n", *
namespace, volume);
503 #ifdef CONFIG_NCPFS_NFS_NS
510 #ifdef CONFIG_NCPFS_OS2_NS
529 int ns = ncp_get_known_namespace(server, volume);
534 DPRINTK(
"lookup_vol: namespace[%d] = %d\n",
544 ncp_ObtainSpecificDirBase(
struct ncp_server *server,
551 ncp_init_request(server);
552 ncp_add_byte(server, 6);
553 ncp_add_byte(server, nsSrc);
554 ncp_add_byte(server, nsDst);
556 ncp_add_dword(server,
RIM_ALL);
557 ncp_add_handle_path(server, vol_num, dir_base, 1, path);
559 if ((result = ncp_request(server, 87)) != 0)
566 *dirEntNum = ncp_reply_dword(server, 0x30);
568 *DosDirNum = ncp_reply_dword(server, 0x34);
582 if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber,
583 dirEntNum,
NULL, newDirEnt, newDosEnt)) != 0)
588 server->
m.mounted_vol[1] = 0;
589 server->
m.mounted_vol[0] =
'X';
599 DPRINTK(
"ncp_get_volume_root: looking up vol %s\n", volname);
601 ncp_init_request(server);
602 ncp_add_byte(server, 22);
603 ncp_add_byte(server, 0);
604 ncp_add_byte(server, 0);
605 ncp_add_byte(server, 0);
606 ncp_add_byte(server, 0);
608 ncp_add_byte(server, 0);
609 ncp_add_dword(server, 0);
610 ncp_add_byte(server, 0xff);
611 ncp_add_byte(server, 1);
612 ncp_add_pstring(server, volname);
614 if ((result = ncp_request(server, 87)) != 0) {
618 *dirent = *dosdirent = ncp_reply_dword(server, 4);
619 *volume = ncp_reply_byte(server, 8);
630 memset(target, 0,
sizeof(*target));
643 target->nfs.mode = 0;
653 __u8 volnum = NCP_FINFO(dir)->volNumber;
654 __le32 dirent = NCP_FINFO(dir)->dirEntNum;
657 ncp_init_request(server);
658 ncp_add_byte(server, 7);
659 ncp_add_byte(server, server->
name_space[volnum]);
660 ncp_add_byte(server, 0);
663 ncp_add_dword(server, info_mask);
664 ncp_add_mem(server, info,
sizeof(*info));
665 ncp_add_handle_path(server, volnum, dirent, 1, path);
667 result = ncp_request(server, 87);
681 #ifdef CONFIG_NCPFS_NFS_NS
688 ncp_init_request(server);
690 ncp_add_byte(server, 25);
691 ncp_add_byte(server, server->
name_space[volnum]);
693 ncp_add_byte(server, volnum);
694 ncp_add_dword(server, dirent);
698 ncp_add_dword_lh(server, mode);
699 ncp_add_dword_lh(server, 1);
700 ncp_add_dword_lh(server, rdev);
701 result = ncp_request(server, 87);
716 ncp_init_request(server);
717 ncp_add_byte(server, 8);
718 ncp_add_byte(server, ns);
719 ncp_add_byte(server, 0);
720 ncp_add_word(server, attr);
721 ncp_add_handle_path(server, volnum, dirent, have_dir_base, name);
723 result = ncp_request(server, 87);
739 volnum = NCP_FINFO(inode)->volNumber;
740 dirent = NCP_FINFO(inode)->DosDirNum;
748 __u8 volnum = NCP_FINFO(dir)->volNumber;
749 __le32 dirent = NCP_FINFO(dir)->dirEntNum;
753 #ifdef CONFIG_NCPFS_NFS_NS
758 result=ncp_obtain_DOS_dir_base(server, name_space, volnum, dirent, name, &dirent);
759 if (result)
return result;
764 return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, name_space,
cpu_to_le16(0x8006));
780 int open_create_mode,
782 __le16 desired_acc_rights,
790 volnum = NCP_FINFO(dir)->volNumber;
791 dirent = NCP_FINFO(dir)->dirEntNum;
793 if ((create_attributes &
aDIR) != 0) {
796 ncp_init_request(server);
797 ncp_add_byte(server, 1);
798 ncp_add_byte(server, server->
name_space[volnum]);
799 ncp_add_byte(server, open_create_mode);
800 ncp_add_word(server, search_attribs);
801 ncp_add_dword(server,
RIM_ALL);
802 ncp_add_dword(server, create_attributes);
805 ncp_add_word(server, desired_acc_rights);
806 ncp_add_handle_path(server, volnum, dirent, 1, name);
808 if ((result = ncp_request(server, 87)) != 0)
810 if (!(create_attributes & aDIR))
815 target->
volume = target->
i.volNumber;
816 ConvertToNWfromDWORD(ncp_reply_le16(server, 0),
817 ncp_reply_le16(server, 2),
834 __u8 volnum = NCP_FINFO(dir)->volNumber;
835 __le32 dirent = NCP_FINFO(dir)->dirEntNum;
838 ncp_init_request(server);
839 ncp_add_byte(server, 2);
840 ncp_add_byte(server, server->
name_space[volnum]);
841 ncp_add_byte(server, 0);
842 ncp_add_handle_path(server, volnum, dirent, 1,
NULL);
844 result = ncp_request(server, 87);
847 memcpy(target, ncp_reply_data(server, 0),
sizeof(*target));
865 ncp_init_request(server);
866 ncp_add_byte(server, 20);
868 ncp_add_byte(server, 0);
870 ncp_add_dword(server,
RIM_ALL);
872 ncp_add_mem(server, seq, 9);
873 #ifdef CONFIG_NCPFS_NFS_NS
875 ncp_add_byte(server, 0);
879 ncp_add_byte(server, 2);
880 ncp_add_byte(server, 0xff);
881 ncp_add_byte(server,
'*');
896 *cnt = WVAL_LH(buffer + 10);
897 *more =
BVAL(buffer + 9);
904 struct inode *old_dir,
const char *old_name,
__le16 old_type,
905 struct inode *new_dir,
const char *new_name)
909 if ((old_dir ==
NULL) || (old_name ==
NULL) ||
910 (new_dir ==
NULL) || (new_name ==
NULL))
913 ncp_init_request(server);
914 ncp_add_byte(server, 4);
916 ncp_add_byte(server, 1);
917 ncp_add_word(server, old_type);
920 ncp_add_byte(server, NCP_FINFO(old_dir)->
volNumber);
921 ncp_add_dword(server, NCP_FINFO(old_dir)->dirEntNum);
922 ncp_add_byte(server, 1);
923 ncp_add_byte(server, 1);
926 ncp_add_byte(server, NCP_FINFO(new_dir)->
volNumber);
927 ncp_add_dword(server, NCP_FINFO(new_dir)->dirEntNum);
928 ncp_add_byte(server, 1);
929 ncp_add_byte(server, 1);
932 ncp_add_pstring(server, old_name);
934 ncp_add_pstring(server, new_name);
936 result = ncp_request(server, 87);
943 struct inode *old_dir,
const char *old_name,
944 struct inode *new_dir,
const char *new_name)
950 result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,
955 result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,
958 if (result != 0x92)
return result;
960 if (result != 0)
return -
EACCES;
961 result = ncp_RenameNSEntry(server, old_dir, old_name, old_type,
975 ncp_init_request(server);
976 ncp_add_byte(server, 0);
977 ncp_add_mem(server, file_id, 6);
978 ncp_add_be32(server, offset);
979 ncp_add_be16(server, to_read);
981 if ((result = ncp_request(server, 72)) != 0) {
984 *bytes_read = ncp_reply_be16(server, 0);
985 source = ncp_reply_data(server, 2 + (offset & 1));
987 memcpy(target, source, *bytes_read);
1011 ncp_init_request(server);
1012 ncp_add_byte(server, 0);
1013 ncp_add_mem(server, file_id, 6);
1014 ncp_add_be32(server, offset);
1015 ncp_add_be16(server, to_read);
1019 int len = get_unaligned_be16((
char *)bounce +
1022 if (len <= to_read) {
1025 source = (
char*)bounce +
1040 const char *source,
int *bytes_written)
1044 ncp_init_request(server);
1045 ncp_add_byte(server, 0);
1046 ncp_add_mem(server, file_id, 6);
1047 ncp_add_be32(server, offset);
1048 ncp_add_be16(server, to_write);
1049 ncp_add_mem(server, source, to_write);
1051 if ((result = ncp_request(server, 73)) == 0)
1052 *bytes_written = to_write;
1057 #ifdef CONFIG_NCPFS_IOCTL_LOCKING
1064 ncp_init_request(server);
1065 ncp_add_byte(server, locktype);
1066 ncp_add_mem(server, file_id, 6);
1067 ncp_add_be32(server, offset);
1068 ncp_add_be32(server, length);
1069 ncp_add_be16(server, timeout);
1071 if ((result = ncp_request(server, 0x1A)) != 0)
1081 ncp_ClearPhysicalRecord(
struct ncp_server *server,
const char *file_id,
1086 ncp_init_request(server);
1087 ncp_add_byte(server, 0);
1088 ncp_add_mem(server, file_id, 6);
1089 ncp_add_be32(server, offset);
1090 ncp_add_be32(server, length);
1092 if ((result = ncp_request(server, 0x1E)) != 0)
1102 #ifdef CONFIG_NCPFS_NLS
1109 const unsigned char *iname,
unsigned int ilen,
int cc)
1113 unsigned char *vname_start;
1114 unsigned char *vname_end;
1115 const unsigned char *iname_end;
1117 iname_end = iname + ilen;
1118 vname_start = vname;
1119 vname_end = vname + *vlen - 1;
1121 while (iname < iname_end) {
1135 if (*iname == NCP_ESC) {
1138 if (iname_end - iname < 5)
1142 for (k = 1; k < 5; k++) {
1145 nc = iname[
k] -
'0';
1147 nc -=
'A' -
'0' - 10;
1148 if ((nc < 10) || (nc > 15)) {
1152 ec = (ec << 4) | nc;
1157 if ( (chl = in->
char2uni(iname, iname_end - iname, &ec)) < 0)
1165 chl = out->
uni2char(ec, vname, vname_end - vname);
1173 for (chi = 0; chi < chl; chi++){
1181 *vlen = vname - vname_start;
1187 const unsigned char *vname,
unsigned int vlen,
int cc)
1191 const unsigned char *vname_end;
1192 unsigned char *iname_start;
1193 unsigned char *iname_end;
1194 unsigned char *vname_cc;
1206 for (i = 0; i < vlen; i++)
1211 iname_start = iname;
1212 iname_end = iname + *ilen - 1;
1213 vname_end = vname + vlen;
1215 while (vname < vname_end) {
1219 if ( (chl = in->
char2uni(vname, vname_end - vname, &ec)) < 0) {
1237 if ( (chl = out->
uni2char(ec, iname, iname_end - iname)) >= 0) {
1242 if (iname_end - iname < 5) {
1247 for (k = 4; k > 0; k--) {
1250 v = (ec & 0xF) +
'0';
1263 *ilen = iname - iname_start;
1275 const unsigned char *iname,
unsigned int ilen,
int cc)
1283 for (i = 0; i < ilen; i++) {
1300 const unsigned char *vname,
unsigned int vlen,
int cc)
1308 for (i = 0; i < vlen; i++) {