📄 ncplib_kernel.c
字号:
if ((result = ncp_request(server, 87)) != 0) goto out; ncp_extract_file_info(ncp_reply_data(server, 0), target); ncp_unlock_server(server); result = ncp_obtain_nfs_info(server, target); return result;out: ncp_unlock_server(server); return result;}#ifdef CONFIG_NCPFS_NFS_NSstatic intncp_obtain_DOS_dir_base(struct ncp_server *server, __u8 volnum, __le32 dirent, char *path, /* At most 1 component */ __le32 *DOS_dir_base){ int result; ncp_init_request(server); ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, server->name_space[volnum]); ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ ncp_add_dword(server, RIM_DIRECTORY); ncp_add_handle_path(server, volnum, dirent, 1, path); if ((result = ncp_request(server, 87)) == 0) { if (DOS_dir_base) *DOS_dir_base=ncp_reply_dword(server, 0x34); } ncp_unlock_server(server); return result;}#endif /* CONFIG_NCPFS_NFS_NS */static inline intncp_get_known_namespace(struct ncp_server *server, __u8 volume){#if defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) int result; __u8 *namespace; __u16 no_namespaces; ncp_init_request(server); ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ ncp_add_word(server, 0); ncp_add_byte(server, volume); if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return NW_NS_DOS; /* not result ?? */ } result = NW_NS_DOS; no_namespaces = ncp_reply_le16(server, 0); namespace = ncp_reply_data(server, 2); while (no_namespaces > 0) { DPRINTK("get_namespaces: found %d on %d\n", *namespace, volume);#ifdef CONFIG_NCPFS_NFS_NS if ((*namespace == NW_NS_NFS) && !(server->m.flags&NCP_MOUNT_NO_NFS)) { result = NW_NS_NFS; break; }#endif /* CONFIG_NCPFS_NFS_NS */#ifdef CONFIG_NCPFS_OS2_NS if ((*namespace == NW_NS_OS2) && !(server->m.flags&NCP_MOUNT_NO_OS2)) { result = NW_NS_OS2; }#endif /* CONFIG_NCPFS_OS2_NS */ namespace += 1; no_namespaces -= 1; } ncp_unlock_server(server); return result;#else /* neither OS2 nor NFS - only DOS */ return NW_NS_DOS;#endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */}static intncp_ObtainSpecificDirBase(struct ncp_server *server, __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base, char *path, /* At most 1 component */ __le32 *dirEntNum, __le32 *DosDirNum){ int result; ncp_init_request(server); ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, nsSrc); ncp_add_byte(server, nsDst); ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ ncp_add_dword(server, RIM_ALL); ncp_add_handle_path(server, vol_num, dir_base, 1, path); if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } if (dirEntNum) *dirEntNum = ncp_reply_dword(server, 0x30); if (DosDirNum) *DosDirNum = ncp_reply_dword(server, 0x34); ncp_unlock_server(server); return 0;}intncp_mount_subdir(struct ncp_server *server, __u8 volNumber, __u8 srcNS, __le32 dirEntNum, __u32* volume, __le32* newDirEnt, __le32* newDosEnt){ int dstNS; int result; dstNS = ncp_get_known_namespace(server, volNumber); if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, dirEntNum, NULL, newDirEnt, newDosEnt)) != 0) { return result; } server->name_space[volNumber] = dstNS; *volume = volNumber; server->m.mounted_vol[1] = 0; server->m.mounted_vol[0] = 'X'; return 0;}int ncp_get_volume_root(struct ncp_server *server, const char *volname, __u32* volume, __le32* dirent, __le32* dosdirent){ int result; __u8 volnum; DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname); ncp_init_request(server); ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ ncp_add_byte(server, 0); /* DOS namespace */ ncp_add_byte(server, 0); /* reserved */ ncp_add_byte(server, 0); /* reserved */ ncp_add_byte(server, 0); /* reserved */ ncp_add_byte(server, 0); /* faked volume number */ ncp_add_dword(server, 0); /* faked dir_base */ ncp_add_byte(server, 0xff); /* Don't have a dir_base */ ncp_add_byte(server, 1); /* 1 path component */ ncp_add_pstring(server, volname); if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } *dirent = *dosdirent = ncp_reply_dword(server, 4); volnum = ncp_reply_byte(server, 8); ncp_unlock_server(server); *volume = volnum; server->name_space[volnum] = ncp_get_known_namespace(server, volnum); DPRINTK("lookup_vol: namespace[%d] = %d\n", volnum, server->name_space[volnum]); return 0;}intncp_lookup_volume(struct ncp_server *server, const char *volname, struct nw_info_struct *target){ int result; memset(target, 0, sizeof(*target)); result = ncp_get_volume_root(server, volname, &target->volNumber, &target->dirEntNum, &target->DosDirNum); if (result) { return result; } target->nameLen = strlen(volname); memcpy(target->entryName, volname, target->nameLen+1); target->attributes = aDIR; /* set dates to Jan 1, 1986 00:00 */ target->creationTime = target->modifyTime = cpu_to_le16(0x0000); target->creationDate = target->modifyDate = target->lastAccessDate = cpu_to_le16(0x0C21); target->nfs.mode = 0; return 0;}int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *server, struct inode *dir, const char *path, __le32 info_mask, const struct nw_modify_dos_info *info){ __u8 volnum = NCP_FINFO(dir)->volNumber; __le32 dirent = NCP_FINFO(dir)->dirEntNum; int result; ncp_init_request(server); ncp_add_byte(server, 7); /* subfunction */ ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, 0); /* reserved */ ncp_add_word(server, cpu_to_le16(0x8006)); /* search attribs: all */ ncp_add_dword(server, info_mask); ncp_add_mem(server, info, sizeof(*info)); ncp_add_handle_path(server, volnum, dirent, 1, path); result = ncp_request(server, 87); ncp_unlock_server(server); return result;}int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, struct inode *dir, __le32 info_mask, const struct nw_modify_dos_info *info){ return ncp_modify_file_or_subdir_dos_info_path(server, dir, NULL, info_mask, info);}#ifdef CONFIG_NCPFS_NFS_NSint ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent, __u32 mode, __u32 rdev){ int result = 0; if (server->name_space[volnum] == NW_NS_NFS) { ncp_init_request(server); ncp_add_byte(server, 25); /* subfunction */ ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, NW_NS_NFS); ncp_add_byte(server, volnum); ncp_add_dword(server, dirent); /* we must always operate on both nlinks and rdev, otherwise rdev is not set */ ncp_add_dword_lh(server, NSIBM_NFS_MODE | NSIBM_NFS_NLINKS | NSIBM_NFS_RDEV); ncp_add_dword_lh(server, mode); ncp_add_dword_lh(server, 1); /* nlinks */ ncp_add_dword_lh(server, rdev); result = ncp_request(server, 87); ncp_unlock_server(server); } return result;}#endifstatic intncp_DeleteNSEntry(struct ncp_server *server, __u8 have_dir_base, __u8 volnum, __le32 dirent, char* name, __u8 ns, __le16 attr){ int result; ncp_init_request(server); ncp_add_byte(server, 8); /* subfunction */ ncp_add_byte(server, ns); ncp_add_byte(server, 0); /* reserved */ ncp_add_word(server, attr); /* search attribs: all */ ncp_add_handle_path(server, volnum, dirent, have_dir_base, name); result = ncp_request(server, 87); ncp_unlock_server(server); return result;}intncp_del_file_or_subdir2(struct ncp_server *server, struct dentry *dentry){ struct inode *inode = dentry->d_inode; __u8 volnum; __le32 dirent; if (!inode) { return 0xFF; /* Any error */ } volnum = NCP_FINFO(inode)->volNumber; dirent = NCP_FINFO(inode)->DosDirNum; return ncp_DeleteNSEntry(server, 1, volnum, dirent, NULL, NW_NS_DOS, cpu_to_le16(0x8006));}intncp_del_file_or_subdir(struct ncp_server *server, struct inode *dir, char *name){ __u8 volnum = NCP_FINFO(dir)->volNumber; __le32 dirent = NCP_FINFO(dir)->dirEntNum;#ifdef CONFIG_NCPFS_NFS_NS if (server->name_space[volnum]==NW_NS_NFS) { int result; result=ncp_obtain_DOS_dir_base(server, volnum, dirent, name, &dirent); if (result) return result; return ncp_DeleteNSEntry(server, 1, volnum, dirent, NULL, NW_NS_DOS, cpu_to_le16(0x8006)); } else#endif /* CONFIG_NCPFS_NFS_NS */ return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, server->name_space[volnum], cpu_to_le16(0x8006));}static inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6]){ __le16 *dest = (__le16 *) ret; dest[1] = cpu_to_le16(v0); dest[2] = cpu_to_le16(v1); dest[0] = cpu_to_le16(v0 + 1); return;}/* If both dir and name are NULL, then in target there's already a looked-up entry that wants to be opened. */int ncp_open_create_file_or_subdir(struct ncp_server *server, struct inode *dir, char *name, int open_create_mode, __le32 create_attributes, __le16 desired_acc_rights, struct ncp_entry_info *target){ __le16 search_attribs = cpu_to_le16(0x0006); __u8 volnum; __le32 dirent; int result; volnum = NCP_FINFO(dir)->volNumber; dirent = NCP_FINFO(dir)->dirEntNum; if ((create_attributes & aDIR) != 0) { search_attribs |= cpu_to_le16(0x8000); } ncp_init_request(server); ncp_add_byte(server, 1); /* subfunction */ ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, open_create_mode); ncp_add_word(server, search_attribs); ncp_add_dword(server, RIM_ALL); ncp_add_dword(server, create_attributes); /* The desired acc rights seem to be the inherited rights mask for directories */ ncp_add_word(server, desired_acc_rights); ncp_add_handle_path(server, volnum, dirent, 1, name); if ((result = ncp_request(server, 87)) != 0) goto out; if (!(create_attributes & aDIR)) target->opened = 1; /* in target there's a new finfo to fill */ ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i)); target->volume = target->i.volNumber; ConvertToNWfromDWORD(ncp_reply_le16(server, 0), ncp_reply_le16(server, 2), target->file_handle); ncp_unlock_server(server); (void)ncp_obtain_nfs_info(server, &(target->i)); return 0;out: ncp_unlock_server(server); return result;}intncp_initialize_search(struct ncp_server *server, struct inode *dir, struct nw_search_sequence *target){ __u8 volnum = NCP_FINFO(dir)->volNumber; __le32 dirent = NCP_FINFO(dir)->dirEntNum; int result; ncp_init_request(server); ncp_add_byte(server, 2); /* subfunction */ ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, 0); /* reserved */ ncp_add_handle_path(server, volnum, dirent, 1, NULL); result = ncp_request(server, 87); if (result) goto out; memcpy(target, ncp_reply_data(server, 0), sizeof(*target));out: ncp_unlock_server(server); return result;}int ncp_search_for_fileset(struct ncp_server *server, struct nw_search_sequence *seq, int* more, int* cnt, char* buffer, size_t bufsize, char** rbuf, size_t* rsize){ int result; ncp_init_request(server); ncp_add_byte(server, 20); ncp_add_byte(server, server->name_space[seq->volNumber]); ncp_add_byte(server, 0); /* datastream */ ncp_add_word(server, cpu_to_le16(0x8006)); ncp_add_dword(server, RIM_ALL); ncp_add_word(server, cpu_to_le16(32767)); /* max returned items */ ncp_add_mem(server, seq, 9);#ifdef CONFIG_NCPFS_NFS_NS if (server->name_space[seq->volNumber] == NW_NS_NFS) { ncp_add_byte(server, 0); /* 0 byte pattern */ } else #endif { ncp_add_byte(server, 2); /* 2 byte pattern */ ncp_add_byte(server, 0xff); /* following is a wildcard */ ncp_add_byte(server, '*'); } result = ncp_request2(server, 87, buffer, bufsize); if (result) { ncp_unlock_server(server); return result;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -