int unistr2charstr(PWSTR unistr, LPCSTR chstr) { struct ethread *thread; struct nls_table *nls; UCHAR *pch; WCHAR *wc; int retval = -EFAULT; int charlen=0; thread = get_current_ethread(); nls = thread ? thread->threads_process->ep_nls : load_nls("cp936"); pch = (UCHAR *)chstr; if(nls){ for(wc = unistr; *wc != 0; wc++){ retval = nls->uni2char(*wc, pch, 2); if(retval>0){ charlen += retval; pch += retval; } else goto out; } *pch = 0; retval = charlen; goto out; } out: if (!thread && nls) unload_nls(nls); return retval; } /* end unistr2charstr() */
void asusnls_u2c(char *name) { #ifdef CONFIG_NLS char *codepage; char *xfrstr; struct nls_table *nls; int ret, len; strcpy(codebuf, name); codepage=codebuf+strlen(NLS_NVRAM_U2C); if((xfrstr=strchr(codepage, '_'))) { *xfrstr=NULL; xfrstr++; nls=load_nls(codepage); if(!nls) { printk("NLS table is null!!\n"); } else { len = 0; //if (ret=utf8_mbstowcs(unibuf, xfrstr, strlen(xfrstr))) if (ret=utf8s_to_utf16s(xfrstr, strlen(xfrstr), unibuf)) { int i; for (i = 0; (i < ret) && unibuf[i]; i++) { int charlen; charlen = nls->uni2char(unibuf[i], &name[len], NLS_MAX_CHARSET_SIZE); if (charlen > 0) { len += charlen; } else { strcpy(name, ""); unload_nls(nls); return; } } name[len] = 0; } unload_nls(nls); if(!len) { printk("can not xfr from utf8 to %s\n", codepage); strcpy(name, ""); } } } else { strcpy(name, ""); } #endif }
static int __init init_nls_euc_jp(void) { p_nls = load_nls("cp932"); if (p_nls) { table.charset2upper = p_nls->charset2upper; table.charset2lower = p_nls->charset2lower; return register_nls(&table); } return -EINVAL; }
static int __init init_nls_koi8_ru(void) { p_nls = load_nls("koi8-u"); if (p_nls) { table.charset2upper = p_nls->charset2upper; table.charset2lower = p_nls->charset2lower; return register_nls(&table); } return -EINVAL; }
void asusnls_c2u(char *name) { #ifdef CONFIG_NLS char *codepage; char *xfrstr; struct nls_table *nls; int ret; strcpy(codebuf, name); codepage=codebuf+strlen(NLS_NVRAM_C2U); if((xfrstr=strchr(codepage, '_'))) { *xfrstr=NULL; xfrstr++; strcpy(name, ""); nls=load_nls(codepage); if(!nls) { printk("NLS table is null!!\n"); } else { int charlen; int i; int len = strlen(xfrstr); for (i = 0; len && *xfrstr; i++, xfrstr += charlen, len -= charlen) { /* string to unicode */ charlen = nls->char2uni(xfrstr, len, &unibuf[i]); if (charlen < 1) { strcpy(name ,""); unload_nls(nls); return; } } unibuf[i] = 0; //ret=utf8_wcstombs(name, unibuf, 1024); /* unicode to utf-8, 1024 is size of array unibuf */ ret=utf16s_to_utf8s(unibuf, i, UTF16_HOST_ENDIAN, name, 1024); /* unicode to utf-8, 1024 is size of array unibuf */ name[ret]=0; unload_nls(nls); if(!ret) { printk("can not xfr from %s to utf8\n", codepage); strcpy(name, ""); } } } else { strcpy(name, ""); } #endif }
static int __init init_nls_euc_jp(void) { p_nls = load_nls("cp932"); if (p_nls) { pax_open_kernel(); *(const unsigned char **)&table.charset2upper = p_nls->charset2upper; *(const unsigned char **)&table.charset2lower = p_nls->charset2lower; pax_close_kernel(); return register_nls(&table); } return -EINVAL; }
static int __init init_nls_gb2312(void) { p_nls = load_nls("cp936"); if (p_nls) { table.uni2char = p_nls->uni2char; table.char2uni = p_nls->char2uni; table.charset2upper = p_nls->charset2upper; table.charset2lower = p_nls->charset2lower; return register_nls(&table); } return -EINVAL; }
static void test_nls_base(void) { wchar_t p=0x20; __u8 s=0x01; int n=2; struct nls_table nls; char charset[20]="David"; load_nls_default(); register_nls(&nls); unload_nls(&nls); load_nls(charset); unregister_nls(&nls); utf8_mbtowc(&p, &s, n); utf8_mbstowcs(&p, &s, n); n=20; utf8_wctomb(&s, p, n); utf8_wcstombs(&s, &p, n); }
// ------------------------------------------- const char *nls2a(const char *i, const char *p) { if (false == nls_loaded) { load_nls(); nls_loaded = true; } if (pNLS) { char buffer[256]; int k; unsigned hash; hash = calc_hash(buffer, i, &k); struct nls *t; dolist (t, pNLS) if (t->hash==hash && 0==memcmp(buffer, t->key, 1+k)) return t->translation; } return p; }
/* input is the options passed to mount() as a string */ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) { char *p; substring_t args[MAX_OPT_ARGS]; int tmp, token; if (!input) goto done; while ((p = strsep(&input, ",")) != NULL) { if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case opt_creator: if (match_fourchar(&args[0], &sbi->creator)) { printk(KERN_ERR "hfs: creator requires a 4 character value\n"); return 0; } break; case opt_type: if (match_fourchar(&args[0], &sbi->type)) { printk(KERN_ERR "hfs: type requires a 4 character value\n"); return 0; } break; case opt_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: umask requires a value\n"); return 0; } sbi->umask = (umode_t)tmp; break; case opt_uid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: uid requires an argument\n"); return 0; } sbi->uid = (uid_t)tmp; break; case opt_gid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: gid requires an argument\n"); return 0; } sbi->gid = (gid_t)tmp; break; case opt_part: if (match_int(&args[0], &sbi->part)) { printk(KERN_ERR "hfs: part requires an argument\n"); return 0; } break; case opt_session: if (match_int(&args[0], &sbi->session)) { printk(KERN_ERR "hfs: session requires an argument\n"); return 0; } break; case opt_nls: if (sbi->nls) { printk(KERN_ERR "hfs: unable to change nls mapping\n"); return 0; } p = match_strdup(&args[0]); if (p) sbi->nls = load_nls(p); if (!sbi->nls) { printk(KERN_ERR "hfs: unable to load " "nls mapping \"%s\"\n", p); kfree(p); return 0; } kfree(p); break; case opt_decompose: clear_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags); break; case opt_nodecompose: set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags); break; case opt_barrier: clear_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags); break; case opt_nobarrier: set_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags); break; case opt_force: set_bit(HFSPLUS_SB_FORCE, &sbi->flags); break; default: return 0; } } done: if (!sbi->nls) { /* try utf8 first, as this is the old default behaviour */ sbi->nls = load_nls("utf8"); if (!sbi->nls) sbi->nls = load_nls_default(); if (!sbi->nls) return 0; } return 1; }
void asusnls_c2u(char *name) { #ifdef CONFIG_NLS char *codepage; char *xfrstr; struct nls_table *nls; int ret; strcpy(codebuf, name); codepage=codebuf+strlen(NLS_NVRAM_C2U); if((xfrstr=strchr(codepage, '_'))) { *xfrstr=NULL; xfrstr++; /* debug message, start */ /* printk("%s, xfr from %s to utf8\n", xfrstr, codepage); printk("local: %d, ", strlen(xfrstr)); int j; for (j=0;j<strlen(xfrstr);j++) printk("%X ", (unsigned char)xfrstr[j]); printk("\n"); printk("local: %s\n", xfrstr); */ /* debug message, end */ strcpy(name, ""); nls=load_nls(codepage); if(!nls) { printk("NLS table is null!!\n"); } else { int charlen; int i; int len = strlen(xfrstr); for (i = 0; len && *xfrstr; i++, xfrstr += charlen, len -= charlen) { /* string to unicode */ charlen = nls->char2uni(xfrstr, len, &unibuf[i]); if (charlen < 1) { //unibuf[i] = 0x003f; /* a question mark */ //charlen = 1; strcpy(name ,""); unload_nls(nls); return; } } unibuf[i] = 0; ret=utf8_wcstombs(name, unibuf, 1024); /* unicode to utf-8, 1024 is size of array unibuf */ name[ret]=0; unload_nls(nls); /* debug message, start */ /* int k; printk("unicode: %d, ", i); for(k=0;k<i;k++) printk("%X ", unibuf[k]); printk("\n"); printk("utf-8: %s, %d, ", name, strlen(name)); for (i=0;i<strlen(name);i++) printk("%X ", (unsigned char)name[i]); printk("\n"); */ /* debug message, end */ if(!ret) { printk("can not xfr from %s to utf8\n", codepage); strcpy(name, ""); } } } else { strcpy(name, ""); } #endif }
void asusnls_u2c(char *name) { #ifdef CONFIG_NLS char *codepage; char *xfrstr; struct nls_table *nls; int ret, len; strcpy(codebuf, name); codepage=codebuf+strlen(NLS_NVRAM_U2C); if((xfrstr=strchr(codepage, '_'))) { *xfrstr=NULL; xfrstr++; /* debug message, start */ /* printk("%s, xfr from utf8 to %s\n", xfrstr, codepage); int j; printk("utf8: %d, ", strlen(xfrstr)); for(j=0;j<strlen(xfrstr);j++) printk("%X ", (unsigned char)xfrstr[j]); printk("\n"); */ /* debug message, end */ nls=load_nls(codepage); if(!nls) { printk("NLS table is null!!\n"); } else { len = 0; if (ret=utf8_mbstowcs(unibuf, xfrstr, strlen(xfrstr))) { int i; for (i = 0; (i < ret) && unibuf[i]; i++) { int charlen; charlen = nls->uni2char(unibuf[i], &name[len], NLS_MAX_CHARSET_SIZE); if (charlen > 0) { len += charlen; } else { //name[len++] = '?'; strcpy(name, ""); unload_nls(nls); return; } } name[len] = 0; } unload_nls(nls); /* debug message, start */ /* int i; printk("unicode: %d, ", ret); for (i=0;i<ret;i++) printk("%X ", unibuf[i]); printk("\n"); printk("local: %d, ", strlen(name)); for (i=0;i<strlen(name);i++) printk("%X ", (unsigned char)name[i]); printk("\n"); printk("local: %s\n", name); */ /* debug message, end */ if(!len) { printk("can not xfr from utf8 to %s\n", codepage); strcpy(name, ""); } } } else { strcpy(name, ""); } #endif }
static APIRET attachVolume(ServerData * pServerData, struct attach * pattach) { VolData * pVolData; IFS_ATTACH * parms = (IFS_ATTACH *) pServerData->pData; int rc; struct iso_primary_descriptor jpd; struct hs_primary_descriptor *hpd; struct iso_directory_record *idr = 0; /* For codepage */ ULONG ulCp[4]; ULONG ulInfoLen=0; char *ptr; pattach->pVolData = 0; if ((pattach->cbParm != sizeof(IFS_ATTACH)) || VERIFYFIXED(parms->szBasePath) ) return ERROR_INVALID_PARAMETER; for (ptr = parms->szBasePath; *ptr; ptr++) if (*ptr == '/') *ptr = '\\'; logMsg(L_DBG, "attaching drive, isopath=%s, offset: %d, charset: %s", parms->szBasePath, parms->iOffset, parms->szCharSet); if ((strncmp(parms->szBasePath, "\\\\", 2) != 0) && /* UNC */ (strncmp(parms->szBasePath, "////", 2) != 0) && /* UNC */ ((strlen(parms->szBasePath) < 3) || (!isalpha((unsigned char) parms->szBasePath[0])) || (parms->szBasePath[1] != ':') || ((parms->szBasePath[2] != '\\') && (parms->szBasePath[2] != '/')))) return ERROR_INVALID_PARAMETER; /* Max sector not tested, yet */ if(parms->iOffset<0) return ERROR_ISOFS_INVALIDOFFSET; /* Allocate a VolData structure. */ pVolData = malloc(sizeof(VolData)); if (!pVolData) { logMsg(L_EVIL, "out of memory"); return ERROR_NOT_ENOUGH_MEMORY; } memset(pVolData,0,sizeof(VolData)); pVolData->pServerData = pServerData; pVolData->chDrive = toupper(pattach->szDev[0]); pVolData->cOpenFiles = 0; pVolData->cSearches = 0; strncpy(pVolData->fileName,parms->szBasePath,sizeof(pVolData->fileName)); pVolData->iSectorOffset=parms->iOffset; strncpy(pVolData->szCharSet,parms->szCharSet,sizeof(pVolData->szCharSet)); /* Load translation table */ if(strlen(pVolData->szCharSet)) { pVolData->nls = load_nls(pVolData->szCharSet); if(!pVolData->nls) logMsg(L_EVIL, "Can't load table for charset %s",pVolData->szCharSet); } else { /* Use default system codepage */ if(DosQueryCp(sizeof(ulCp),ulCp,&ulInfoLen)==NO_ERROR) { /* Check if mkisofs supports our CP */ if(checkCpSupport((int)ulCp[0])) { sprintf(pVolData->szCharSet,"cp%d",(int)ulCp[0]); pVolData->nls = load_nls(pVolData->szCharSet); if(!pVolData->nls) logMsg(L_EVIL, "Can't load table for system codepage %s",pVolData->szCharSet); } } } /* ISO file */ pVolData->isoFile=sysOpenFile(pVolData->fileName, SOF_FAIL_IF_NEW | SOF_OPEN_IF_EXISTS | SOF_DENYWRITE | SOF_READONLY, 0); if(!pVolData->isoFile) { logMsg(L_EVIL, "Can't open ISO file"); /* Unload translation table */ if(pVolData->nls) unload_nls(pVolData->nls); free(pVolData); return ERROR_ISOFS_FILEOPEN; } /* Get info from ISO file */ lseek(pVolData->isoFile->h, ((off_t)(16 + pVolData->iSectorOffset)) <<11, 0); rc=read(pVolData->isoFile->h, &pVolData->ipd, sizeof(pVolData->ipd)); logMsg(L_DBG, "ISO primary descriptor read from ISO file (%d Bytes)",rc); /****************************************/ hpd = (struct hs_primary_descriptor *) &pVolData->ipd; if ((hpd->type[0] == ISO_VD_PRIMARY) && (strncmp(hpd->id, HIGH_SIERRA_ID, sizeof(hpd->id)) == 0) && (hpd->version[0] == 1)) { pVolData->high_sierra = 1; idr = (struct iso_directory_record *) hpd->root_directory_record; memcpy(&pVolData->chrCDName,&hpd->volume_id,32); } else if ((pVolData->ipd.type[0] != ISO_VD_PRIMARY) || (strncmp(pVolData->ipd.id, ISO_STANDARD_ID, sizeof(pVolData->ipd.id)) != 0) || (pVolData->ipd.version[0] != 1)) { logMsg(L_EVIL, "Unable to find PVD"); /* Unload translation table */ if(pVolData->nls) unload_nls(pVolData->nls); sysCloseFile(pVolData->isoFile); free(pVolData); return ERROR_ISOFS_NOTISO; } if (!pVolData->high_sierra) { int block = 16; memcpy(&pVolData->chrCDName,&pVolData->ipd.volume_id,32); memcpy(&jpd, &pVolData->ipd, sizeof(pVolData->ipd)); while (((unsigned char) jpd.type[0] != ISO_VD_END) && (strncmp(jpd.id, ISO_STANDARD_ID, sizeof(jpd.id)) == 0) && (jpd.version[0] == 1)) { if( (unsigned char) jpd.type[0] == ISO_VD_SUPPLEMENTARY ) /* * Find the UCS escape sequence. */ if( jpd.escape_sequences[0] == '%' && jpd.escape_sequences[1] == '/' && (jpd.escape_sequences[3] == '\0' || jpd.escape_sequences[3] == ' ') && (jpd.escape_sequences[2] == '@' || jpd.escape_sequences[2] == 'C' || jpd.escape_sequences[2] == 'E') ) { pVolData->got_joliet = 1; break; } block++; lseek(pVolData->isoFile->h, ((off_t)(block + pVolData->iSectorOffset)) <<11, 0); read(pVolData->isoFile->h, &jpd, sizeof(jpd)); } if(pVolData->got_joliet) switch(jpd.escape_sequences[2]) { case '@': pVolData->ucs_level = 1; break; case 'C': pVolData->ucs_level = 2; break; case 'E': pVolData->ucs_level = 3; break; } if (pVolData->got_joliet) memcpy(&pVolData->ipd, &jpd, sizeof(pVolData->ipd)); idr = (struct iso_directory_record *) pVolData->ipd.root_directory_record; } /****************************************/ /* Fill in extent of root */ pVolData->root_directory_record = idr; pVolData->idRoot = isonum_733((unsigned char *)idr->extent);/* 733 */ pVolData->iRootExtent = pVolData->idRoot; pVolData->iRootSize=isonum_733((unsigned char *)idr->size); logMsg(L_DBG, "Extent of root is: %d ",pVolData->idRoot); pattach->pVolData = pVolData; pVolData->pNext = pServerData->pFirstVolume; pVolData->pPrev = 0; if (pVolData->pNext) pVolData->pNext->pPrev = pVolData; pServerData->pFirstVolume = pVolData; return NO_ERROR; }
NTSTATUS Ext2ProcessGlobalProperty( IN PDEVICE_OBJECT DeviceObject, IN PEXT2_VOLUME_PROPERTY3 Property3, IN ULONG Length ) { PEXT2_VOLUME_PROPERTY3 Property2 = (PVOID)Property3; PEXT2_VOLUME_PROPERTY Property = (PVOID)Property3; struct nls_table * PageTable = NULL; NTSTATUS Status = STATUS_SUCCESS; BOOLEAN GlobalDataResourceAcquired = FALSE; __try { if (Length < 8 || !IsFlagOn(Property->Flags, EXT2_FLAG_VP_SET_GLOBAL)) { Status = STATUS_INVALID_PARAMETER; __leave; } /* query Ext2Fsd's version and built date/time*/ if (Property->Command == APP_CMD_QUERY_VERSION) { PEXT2_VOLUME_PROPERTY_VERSION PVPV = (PEXT2_VOLUME_PROPERTY_VERSION) Property; if (Length < sizeof(EXT2_VOLUME_PROPERTY_VERSION)) { Status = STATUS_INVALID_PARAMETER; __leave; } RtlZeroMemory(&PVPV->Date[0], 0x20); RtlZeroMemory(&PVPV->Time[0], 0x20); RtlZeroMemory(&PVPV->Version[0],0x1C); strncpy(&PVPV->Version[0], gVersion, 0x1B); strncpy(&PVPV->Date[0], gDate, 0x1F); strncpy(&PVPV->Time[0], gTime, 0x1F); __leave; } /* must be property query/set commands */ if (Property->Command == APP_CMD_SET_PROPERTY) { if (Length < sizeof(EXT2_VOLUME_PROPERTY)) { Status = STATUS_INVALID_PARAMETER; __leave; } } else if (Property->Command == APP_CMD_SET_PROPERTY2) { if (Length < sizeof(EXT2_VOLUME_PROPERTY2)) { Status = STATUS_INVALID_PARAMETER; __leave; } } else if (Property->Command == APP_CMD_SET_PROPERTY3) { if (Length < sizeof(EXT2_VOLUME_PROPERTY3)) { Status = STATUS_INVALID_PARAMETER; __leave; } } else { Status = STATUS_INVALID_PARAMETER; __leave; } ExAcquireResourceExclusiveLite(&Ext2Global->Resource, TRUE); GlobalDataResourceAcquired = TRUE; switch (Property->Command) { case APP_CMD_SET_PROPERTY3: if (Property3->Flags2 & EXT2_VPROP3_AUTOMOUNT) { if (Property3->AutoMount) SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); else ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); } case APP_CMD_SET_PROPERTY2: RtlZeroMemory(Ext2Global->sHidingPrefix, HIDINGPAT_LEN); if ((Ext2Global->bHidingPrefix = Property2->bHidingPrefix)) { RtlCopyMemory( Ext2Global->sHidingPrefix, Property2->sHidingPrefix, HIDINGPAT_LEN - 1); } RtlZeroMemory(Ext2Global->sHidingSuffix, HIDINGPAT_LEN); if ((Ext2Global->bHidingSuffix = Property2->bHidingSuffix)) { RtlCopyMemory( Ext2Global->sHidingSuffix, Property2->sHidingSuffix, HIDINGPAT_LEN - 1); } case APP_CMD_SET_PROPERTY: if (Property->bReadonly) { ClearLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } else { SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); if (Property->bExt3Writable) { SetLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } else { ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } } PageTable = load_nls(Property->Codepage); if (PageTable) { memcpy(Ext2Global->Codepage.AnsiName, Property->Codepage, CODEPAGE_MAXLEN); Ext2Global->Codepage.PageTable = PageTable; } break; default: break; } } __finally { if (GlobalDataResourceAcquired) { ExReleaseResourceLite(&Ext2Global->Resource); } } return Status; }
/* * parse_options() * * adapted from linux/fs/msdos/inode.c written 1992,93 by Werner Almesberger * This function is called by hfs_read_super() to parse the mount options. */ static int parse_options(char *options, struct hfs_sb_info *hsb) { char *p; substring_t args[MAX_OPT_ARGS]; int tmp, token; /* initialize the sb with defaults */ hsb->s_uid = current_uid(); hsb->s_gid = current_gid(); hsb->s_file_umask = 0133; hsb->s_dir_umask = 0022; hsb->s_type = hsb->s_creator = cpu_to_be32(0x3f3f3f3f); /* == '????' */ hsb->s_quiet = 0; hsb->part = -1; hsb->session = -1; if (!options) return 1; while ((p = strsep(&options, ",")) != NULL) { if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case opt_uid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: uid requires an argument\n"); return 0; } hsb->s_uid = (uid_t)tmp; break; case opt_gid: if (match_int(&args[0], &tmp)) { printk(KERN_ERR "hfs: gid requires an argument\n"); return 0; } hsb->s_gid = (gid_t)tmp; break; case opt_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: umask requires a value\n"); return 0; } hsb->s_file_umask = (umode_t)tmp; hsb->s_dir_umask = (umode_t)tmp; break; case opt_file_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: file_umask requires a value\n"); return 0; } hsb->s_file_umask = (umode_t)tmp; break; case opt_dir_umask: if (match_octal(&args[0], &tmp)) { printk(KERN_ERR "hfs: dir_umask requires a value\n"); return 0; } hsb->s_dir_umask = (umode_t)tmp; break; case opt_part: if (match_int(&args[0], &hsb->part)) { printk(KERN_ERR "hfs: part requires an argument\n"); return 0; } break; case opt_session: if (match_int(&args[0], &hsb->session)) { printk(KERN_ERR "hfs: session requires an argument\n"); return 0; } break; case opt_type: if (match_fourchar(&args[0], &hsb->s_type)) { printk(KERN_ERR "hfs: type requires a 4 character value\n"); return 0; } break; case opt_creator: if (match_fourchar(&args[0], &hsb->s_creator)) { printk(KERN_ERR "hfs: creator requires a 4 character value\n"); return 0; } break; case opt_quiet: hsb->s_quiet = 1; break; case opt_codepage: if (hsb->nls_disk) { printk(KERN_ERR "hfs: unable to change codepage\n"); return 0; } p = match_strdup(&args[0]); if (p) hsb->nls_disk = load_nls(p); if (!hsb->nls_disk) { printk(KERN_ERR "hfs: unable to load codepage \"%s\"\n", p); kfree(p); return 0; } kfree(p); break; case opt_iocharset: if (hsb->nls_io) { printk(KERN_ERR "hfs: unable to change iocharset\n"); return 0; } p = match_strdup(&args[0]); if (p) hsb->nls_io = load_nls(p); if (!hsb->nls_io) { printk(KERN_ERR "hfs: unable to load iocharset \"%s\"\n", p); kfree(p); return 0; } kfree(p); break; default: return 0; } } if (hsb->nls_disk && !hsb->nls_io) { hsb->nls_io = load_nls_default(); if (!hsb->nls_io) { printk(KERN_ERR "hfs: unable to load default iocharset\n"); return 0; } } hsb->s_dir_umask &= 0777; hsb->s_file_umask &= 0577; return 1; }
static int udf_parse_options(char *options, struct udf_options *uopt) { char *opt, *val; uopt->novrs = 0; uopt->blocksize = 2048; uopt->partition = 0xFFFF; uopt->session = 0xFFFFFFFF; uopt->lastblock = 0; uopt->anchor = 0; uopt->volume = 0xFFFFFFFF; uopt->rootdir = 0xFFFFFFFF; uopt->fileset = 0xFFFFFFFF; uopt->nls_map = NULL; if (!options) return 1; for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { /* Make "opt=val" into two strings */ val = strchr(opt, '='); if (val) *(val++) = 0; if (!strcmp(opt, "novrs") && !val) uopt->novrs = 1; else if (!strcmp(opt, "bs") && val) uopt->blocksize = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "unhide") && !val) uopt->flags |= (1 << UDF_FLAG_UNHIDE); else if (!strcmp(opt, "undelete") && !val) uopt->flags |= (1 << UDF_FLAG_UNDELETE); else if (!strcmp(opt, "noadinicb") && !val) uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB); else if (!strcmp(opt, "adinicb") && !val) uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB); else if (!strcmp(opt, "shortad") && !val) uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD); else if (!strcmp(opt, "longad") && !val) uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD); else if (!strcmp(opt, "gid") && val) uopt->gid = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "umask") && val) uopt->umask = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "nostrict") && !val) uopt->flags &= ~(1 << UDF_FLAG_STRICT); else if (!strcmp(opt, "uid") && val) uopt->uid = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "session") && val) uopt->session = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "lastblock") && val) uopt->lastblock = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "anchor") && val) uopt->anchor = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "volume") && val) uopt->volume = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "partition") && val) uopt->partition = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "fileset") && val) uopt->fileset = simple_strtoul(val, NULL, 0); else if (!strcmp(opt, "rootdir") && val) uopt->rootdir = simple_strtoul(val, NULL, 0); #ifdef CONFIG_NLS else if (!strcmp(opt, "iocharset") && val) { uopt->nls_map = load_nls(val); uopt->flags |= (1 << UDF_FLAG_NLS_MAP); } #endif else if (!strcmp(opt, "utf8") && !val) uopt->flags |= (1 << UDF_FLAG_UTF8); else if (val) { printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n", opt, val); return 0; } else { printk(KERN_ERR "udf: bad mount option \"%s\"\n", opt); return 0; } } return 1; }
static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) { struct hfsplus_vh *vhdr; struct hfsplus_sb_info *sbi; hfsplus_cat_entry entry; struct hfs_find_data fd; struct inode *root, *inode; struct qstr str; struct nls_table *nls = NULL; int err; err = -EINVAL; sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) goto out; sb->s_fs_info = sbi; mutex_init(&sbi->alloc_mutex); mutex_init(&sbi->vh_mutex); hfsplus_fill_defaults(sbi); err = -EINVAL; if (!hfsplus_parse_options(data, sbi)) { printk(KERN_ERR "hfs: unable to parse mount options\n"); goto out_unload_nls; } /* temporarily use utf8 to correctly find the hidden dir below */ nls = sbi->nls; sbi->nls = load_nls("utf8"); if (!sbi->nls) { printk(KERN_ERR "hfs: unable to load nls for utf8\n"); goto out_unload_nls; } /* Grab the volume header */ if (hfsplus_read_wrapper(sb)) { if (!silent) printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n"); goto out_unload_nls; } vhdr = sbi->s_vhdr; /* Copy parts of the volume header into the superblock */ sb->s_magic = HFSPLUS_VOLHEAD_SIG; if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { printk(KERN_ERR "hfs: wrong filesystem version\n"); goto out_free_vhdr; } sbi->total_blocks = be32_to_cpu(vhdr->total_blocks); sbi->free_blocks = be32_to_cpu(vhdr->free_blocks); sbi->next_cnid = be32_to_cpu(vhdr->next_cnid); sbi->file_count = be32_to_cpu(vhdr->file_count); sbi->folder_count = be32_to_cpu(vhdr->folder_count); sbi->data_clump_blocks = be32_to_cpu(vhdr->data_clump_sz) >> sbi->alloc_blksz_shift; if (!sbi->data_clump_blocks) sbi->data_clump_blocks = 1; sbi->rsrc_clump_blocks = be32_to_cpu(vhdr->rsrc_clump_sz) >> sbi->alloc_blksz_shift; if (!sbi->rsrc_clump_blocks) sbi->rsrc_clump_blocks = 1; /* Set up operations so we can load metadata */ sb->s_op = &hfsplus_sops; sb->s_maxbytes = MAX_LFS_FILESIZE; if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { printk(KERN_WARNING "hfs: Filesystem was " "not cleanly unmounted, " "running fsck.hfsplus is recommended. " "mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } else if (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) { /* nothing */ } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && !(sb->s_flags & MS_RDONLY)) { printk(KERN_WARNING "hfs: write access to " "a journaled filesystem is not supported, " "use the force option at your own risk, " "mounting read-only.\n"); sb->s_flags |= MS_RDONLY; } /* Load metadata objects (B*Trees) */ sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); if (!sbi->ext_tree) { printk(KERN_ERR "hfs: failed to load extents file\n"); goto out_free_vhdr; } sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); if (!sbi->cat_tree) { printk(KERN_ERR "hfs: failed to load catalog file\n"); goto out_close_ext_tree; } inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); if (IS_ERR(inode)) { printk(KERN_ERR "hfs: failed to load allocation file\n"); err = PTR_ERR(inode); goto out_close_cat_tree; } sbi->alloc_file = inode; /* Load the root directory */ root = hfsplus_iget(sb, HFSPLUS_ROOT_CNID); if (IS_ERR(root)) { printk(KERN_ERR "hfs: failed to load root directory\n"); err = PTR_ERR(root); goto out_put_alloc_file; } str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; str.name = HFSP_HIDDENDIR_NAME; hfs_find_init(sbi->cat_tree, &fd); hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str); if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { hfs_find_exit(&fd); if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) goto out_put_root; inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id)); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out_put_root; } sbi->hidden_dir = inode; } else hfs_find_exit(&fd); if (!(sb->s_flags & MS_RDONLY)) { /* * H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused * all three are registered with Apple for our use */ vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); vhdr->modify_date = hfsp_now2mt(); be32_add_cpu(&vhdr->write_count, 1); vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); hfsplus_sync_fs(sb, 1); if (!sbi->hidden_dir) { mutex_lock(&sbi->vh_mutex); sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); hfsplus_create_cat(sbi->hidden_dir->i_ino, root, &str, sbi->hidden_dir); mutex_unlock(&sbi->vh_mutex); hfsplus_mark_inode_dirty(sbi->hidden_dir, HFSPLUS_I_CAT_DIRTY); } } sb->s_d_op = &hfsplus_dentry_operations; sb->s_root = d_alloc_root(root); if (!sb->s_root) { err = -ENOMEM; goto out_put_hidden_dir; } unload_nls(sbi->nls); sbi->nls = nls; return 0; out_put_hidden_dir: iput(sbi->hidden_dir); out_put_root: iput(root); out_put_alloc_file: iput(sbi->alloc_file); out_close_cat_tree: hfs_btree_close(sbi->cat_tree); out_close_ext_tree: hfs_btree_close(sbi->ext_tree); out_free_vhdr: kfree(sbi->s_vhdr); kfree(sbi->s_backup_vhdr); out_unload_nls: unload_nls(sbi->nls); unload_nls(nls); kfree(sbi); out: return err; }
/* Parse the (re)mount options. */ static int parse_options(ntfs_volume *vol, char *opt) { char *value; /* Defaults if not specified and !remount. */ ntfs_uid_t uid = -1; /* 0, root user only */ ntfs_gid_t gid = -1; /* 0, root user only */ int umask = -1; /* 0077, owner access only */ unsigned int ngt = -1; /* ngt_nt */ void *nls_map = NULL; /* Try to load the default NLS. */ int use_utf8 = -1; /* If no NLS specified and loading the default NLS failed use utf8. */ int mft_zone_mul = -1; /* 1 */ if (!opt) goto done; for (opt = strtok(opt, ","); opt; opt = strtok(NULL, ",")) { if ((value = strchr(opt, '=')) != NULL) *value ++= '\0'; if (strcmp(opt, "uid") == 0) { if (!value || !*value) goto needs_arg; uid = simple_strtoul(value, &value, 0); if (*value) { printk(KERN_ERR "NTFS: uid invalid argument\n"); return 0; } } else if (strcmp(opt, "gid") == 0) { if (!value || !*value) goto needs_arg; gid = simple_strtoul(value, &value, 0); if (*value) { printk(KERN_ERR "NTFS: gid invalid argument\n"); return 0; } } else if (strcmp(opt, "umask") == 0) { if (!value || !*value) goto needs_arg; umask = simple_strtoul(value, &value, 0); if (*value) { printk(KERN_ERR "NTFS: umask invalid " "argument\n"); return 0; } } else if (strcmp(opt, "mft_zone_multiplier") == 0) { unsigned long ul; if (!value || !*value) goto needs_arg; ul = simple_strtoul(value, &value, 0); if (*value) { printk(KERN_ERR "NTFS: mft_zone_multiplier " "invalid argument\n"); return 0; } if (ul >= 1 && ul <= 4) mft_zone_mul = ul; else { mft_zone_mul = 1; printk(KERN_WARNING "NTFS: mft_zone_multiplier " "out of range. Setting to 1.\n"); } } else if (strcmp(opt, "posix") == 0) { int val; if (!value || !*value) goto needs_arg; if (!simple_getbool(value, &val)) goto needs_bool; ngt = val ? ngt_posix : ngt_nt; } else if (strcmp(opt, "show_sys_files") == 0) { int val = 0; if (!value || !*value) val = 1; else if (!simple_getbool(value, &val)) goto needs_bool; ngt = val ? ngt_full : ngt_nt; } else if (strcmp(opt, "iocharset") == 0) { if (!value || !*value) goto needs_arg; nls_map = load_nls(value); if (!nls_map) { printk(KERN_ERR "NTFS: charset not found"); return 0; } } else if (strcmp(opt, "utf8") == 0) { int val = 0; if (!value || !*value) val = 1; else if (!simple_getbool(value, &val)) goto needs_bool; use_utf8 = val; } else { printk(KERN_ERR "NTFS: unkown option '%s'\n", opt); return 0; } } done: if (use_utf8 == -1) { /* utf8 was not specified at all. */ if (!nls_map) { /* * No NLS was specified. If first mount, load the * default NLS, otherwise don't change the NLS setting. */ if (vol->nls_map == (void*)-1) vol->nls_map = load_nls_default(); } else { /* If an NLS was already loaded, unload it first. */ if (vol->nls_map && vol->nls_map != (void*)-1) unload_nls(vol->nls_map); /* Use the specified NLS. */ vol->nls_map = nls_map; } } else { /* utf8 was specified. */ if (use_utf8 && nls_map) { unload_nls(nls_map); printk(KERN_ERR "NTFS: utf8 cannot be combined with " "iocharset.\n"); return 0; } /* If an NLS was already loaded, unload it first. */ if (vol->nls_map && vol->nls_map != (void*)-1) unload_nls(vol->nls_map); if (!use_utf8) { /* utf8 was specified as false. */ if (!nls_map) /* No NLS was specified, load the default. */ vol->nls_map = load_nls_default(); else /* Use the specified NLS. */ vol->nls_map = nls_map; } else /* utf8 was specified as true. */ vol->nls_map = NULL; } if (uid != -1) vol->uid = uid; if (gid != -1) vol->gid = gid; if (umask != -1) vol->umask = (ntmode_t)umask; if (ngt != -1) vol->ngt = ngt; if (mft_zone_mul != -1) { /* mft_zone_multiplier was specified. */ if (vol->mft_zone_multiplier != -1) { /* This is a remount, ignore a change and warn user. */ if (vol->mft_zone_multiplier != mft_zone_mul) printk(KERN_WARNING "NTFS: Ignoring changes in " "mft_zone_multiplier on " "remount. If you want to " "change this you need to " "umount and mount again.\n"); } else /* Use the specified multiplier. */ vol->mft_zone_multiplier = mft_zone_mul; } else if (vol->mft_zone_multiplier == -1) /* No multiplier specified and first mount, so set default. */ vol->mft_zone_multiplier = 1; return 1; needs_arg: printk(KERN_ERR "NTFS: %s needs an argument", opt); return 0; needs_bool: printk(KERN_ERR "NTFS: %s needs boolean argument", opt); return 0; }
/* allocate global info, try to map host share */ static int sf_glob_alloc(struct vbsf_mount_info_new *info, struct sf_glob_info **sf_gp) { int err, rc; SHFLSTRING *str_name; size_t name_len, str_len; struct sf_glob_info *sf_g; TRACE(); sf_g = kmalloc(sizeof(*sf_g), GFP_KERNEL); if (!sf_g) { err = -ENOMEM; LogRelFunc(("could not allocate memory for global info\n")); goto fail0; } RT_ZERO(*sf_g); if ( info->nullchar != '\0' || info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0 || info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1 || info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2) { /* An old version of mount.vboxsf made the syscall. Translate the * old parameters to the new structure. */ struct vbsf_mount_info_old *info_old = (struct vbsf_mount_info_old *)info; static struct vbsf_mount_info_new info_compat; info = &info_compat; memset(info, 0, sizeof(*info)); memcpy(&info->name, &info_old->name, MAX_HOST_NAME); memcpy(&info->nls_name, &info_old->nls_name, MAX_NLS_NAME); info->length = offsetof(struct vbsf_mount_info_new, dmode); info->uid = info_old->uid; info->gid = info_old->gid; info->ttl = info_old->ttl; } info->name[sizeof(info->name) - 1] = 0; info->nls_name[sizeof(info->nls_name) - 1] = 0; name_len = strlen(info->name); if (name_len > 0xfffe) { err = -ENAMETOOLONG; LogFunc(("map name too big\n")); goto fail1; } str_len = offsetof(SHFLSTRING, String.utf8) + name_len + 1; str_name = kmalloc(str_len, GFP_KERNEL); if (!str_name) { err = -ENOMEM; LogRelFunc(("could not allocate memory for host name\n")); goto fail1; } str_name->u16Length = name_len; str_name->u16Size = name_len + 1; memcpy(str_name->String.utf8, info->name, name_len + 1); if (info->nls_name[0] && strcmp(info->nls_name, "utf8")) { sf_g->nls = load_nls(info->nls_name); if (!sf_g->nls) { err = -EINVAL; LogFunc(("failed to load nls %s\n", info->nls_name)); goto fail1; } } else sf_g->nls = NULL; rc = vboxCallMapFolder(&client_handle, str_name, &sf_g->map); kfree(str_name); if (RT_FAILURE(rc)) { err = -EPROTO; LogFunc(("vboxCallMapFolder failed rc=%d\n", rc)); goto fail2; } sf_g->ttl = info->ttl; sf_g->uid = info->uid; sf_g->gid = info->gid; if ((unsigned)info->length >= sizeof(struct vbsf_mount_info_new)) { /* new fields */ sf_g->dmode = info->dmode; sf_g->fmode = info->fmode; sf_g->dmask = info->dmask; sf_g->fmask = info->fmask; } else { sf_g->dmode = ~0; sf_g->fmode = ~0; } *sf_gp = sf_g; return 0; fail2: if (sf_g->nls) unload_nls(sf_g->nls); fail1: kfree(sf_g); fail0: return err; }
NTSTATUS Ext2ProcessVolumeProperty( IN PEXT2_VCB Vcb, IN PEXT2_VOLUME_PROPERTY3 Property3, IN ULONG Length ) { struct nls_table * PageTable = NULL; PEXT2_VOLUME_PROPERTY2 Property2 = (PVOID)Property3; PEXT2_VOLUME_PROPERTY Property = (PVOID)Property3; NTSTATUS Status = STATUS_SUCCESS; BOOLEAN VcbResourceAcquired = FALSE; __try { ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE); VcbResourceAcquired = TRUE; if (Property->Command == APP_CMD_SET_PROPERTY || Property->Command == APP_CMD_QUERY_PROPERTY) { if (Length < sizeof(EXT2_VOLUME_PROPERTY)) { Status = STATUS_INVALID_PARAMETER; __leave; } } else if (Property->Command == APP_CMD_SET_PROPERTY2 || Property->Command == APP_CMD_QUERY_PROPERTY2) { if (Length < sizeof(EXT2_VOLUME_PROPERTY2)) { Status = STATUS_INVALID_PARAMETER; __leave; } } else if (Property->Command == APP_CMD_SET_PROPERTY3 || Property->Command == APP_CMD_QUERY_PROPERTY3) { if (Length < sizeof(EXT2_VOLUME_PROPERTY3)) { Status = STATUS_INVALID_PARAMETER; __leave; } } switch (Property->Command) { case APP_CMD_SET_PROPERTY3: if (Property3->Flags2 & EXT2_VPROP3_AUTOMOUNT) { if (Property3->AutoMount) SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); else ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); } if (Property3->Flags2 & EXT2_VPROP3_USERIDS) { SetFlag(Vcb->Flags, VCB_USER_IDS); Vcb->uid = Property3->uid; Vcb->gid = Property3->gid; if (Property3->EIDS) { Vcb->euid = Property3->euid; Vcb->egid = Property3->egid; SetFlag(Vcb->Flags, VCB_USER_EIDS); } else { Vcb->euid = Vcb->egid = 0; ClearFlag(Vcb->Flags, VCB_USER_EIDS); } } else { ClearFlag(Vcb->Flags, VCB_USER_IDS); ClearFlag(Vcb->Flags, VCB_USER_EIDS); Vcb->uid = Vcb->gid = 0; Vcb->euid = Vcb->egid = 0; } case APP_CMD_SET_PROPERTY2: RtlZeroMemory(Vcb->sHidingPrefix, HIDINGPAT_LEN); if (Vcb->bHidingPrefix = Property2->bHidingPrefix) { RtlCopyMemory( Vcb->sHidingPrefix, Property2->sHidingPrefix, HIDINGPAT_LEN - 1); } RtlZeroMemory(Vcb->sHidingSuffix, HIDINGPAT_LEN); if (Vcb->bHidingSuffix = Property2->bHidingSuffix) { RtlCopyMemory( Vcb->sHidingSuffix, Property2->sHidingSuffix, HIDINGPAT_LEN - 1); } Vcb->DrvLetter = Property2->DrvLetter; case APP_CMD_SET_PROPERTY: if (Property->bReadonly) { if (IsFlagOn(Vcb->Flags, VCB_INITIALIZED)) { Ext2FlushFiles(NULL, Vcb, FALSE); Ext2FlushVolume(NULL, Vcb, FALSE); } SetLongFlag(Vcb->Flags, VCB_READ_ONLY); } else { if (Property->bExt3Writable) { SetLongFlag(Vcb->Flags, VCB_FORCE_WRITING); } if (!Vcb->IsExt3fs) { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); } else if (!Property->bExt3Writable) { SetLongFlag(Vcb->Flags, VCB_READ_ONLY); } else if (IsFlagOn(Vcb->Flags, VCB_JOURNAL_RECOVER)) { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); Ext2RecoverJournal(NULL, Vcb); if (IsFlagOn(Vcb->Flags, VCB_JOURNAL_RECOVER)) { SetLongFlag(Vcb->Flags, VCB_READ_ONLY); } else { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); } } else { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); } } PageTable = load_nls(Property->Codepage); memcpy(Vcb->Codepage.AnsiName, Property->Codepage, CODEPAGE_MAXLEN); Vcb->Codepage.PageTable = PageTable; if (Vcb->Codepage.PageTable) { Ext2InitializeLabel(Vcb, Vcb->SuperBlock); } break; case APP_CMD_QUERY_PROPERTY3: if (IsFlagOn(Ext2Global->Flags, EXT2_AUTO_MOUNT)) { SetFlag(Property3->Flags2, EXT2_VPROP3_AUTOMOUNT); Property3->AutoMount = TRUE; } else { ClearFlag(Property3->Flags2, EXT2_VPROP3_AUTOMOUNT); Property3->AutoMount = FALSE; } if (IsFlagOn(Vcb->Flags, VCB_USER_IDS)) { SetFlag(Property3->Flags2, EXT2_VPROP3_USERIDS); Property3->uid = Vcb->uid; Property3->gid = Vcb->gid; if (IsFlagOn(Vcb->Flags, VCB_USER_EIDS)) { Property3->EIDS = TRUE; Property3->euid = Vcb->euid; Property3->egid = Vcb->egid; } else { Property3->EIDS = FALSE; } } else { ClearFlag(Property3->Flags2, EXT2_VPROP3_USERIDS); } case APP_CMD_QUERY_PROPERTY2: RtlCopyMemory(Property2->UUID, Vcb->SuperBlock->s_uuid, 16); Property2->DrvLetter = Vcb->DrvLetter; if (Property2->bHidingPrefix = Vcb->bHidingPrefix) { RtlCopyMemory( Property2->sHidingPrefix, Vcb->sHidingPrefix, HIDINGPAT_LEN); } else { RtlZeroMemory( Property2->sHidingPrefix, HIDINGPAT_LEN); } if (Property2->bHidingSuffix = Vcb->bHidingSuffix) { RtlCopyMemory( Property2->sHidingSuffix, Vcb->sHidingSuffix, HIDINGPAT_LEN); } else { RtlZeroMemory( Property2->sHidingSuffix, HIDINGPAT_LEN); } case APP_CMD_QUERY_PROPERTY: Property->bExt2 = TRUE; Property->bExt3 = Vcb->IsExt3fs; Property->bReadonly = IsFlagOn(Vcb->Flags, VCB_READ_ONLY); if (!Property->bReadonly && Vcb->IsExt3fs) { Property->bExt3Writable = TRUE; } else { Property->bExt3Writable = FALSE; } RtlZeroMemory(Property->Codepage, CODEPAGE_MAXLEN); if (Vcb->Codepage.PageTable) { strncpy(Property->Codepage, Vcb->Codepage.PageTable->charset, CODEPAGE_MAXLEN); } else { strncpy(Property->Codepage, "default", CODEPAGE_MAXLEN); } break; default: Status = STATUS_INVALID_PARAMETER; break; } } __finally { if (VcbResourceAcquired) { ExReleaseResourceLite(&Vcb->MainResource); } } return Status; }
/* Allocate private field of the superblock, fill it. * * Finish filling the public superblock fields * Make the root directory * Load a set of NLS translations if needed. */ static int befs_fill_super(struct super_block *sb, void *data, int silent) { struct buffer_head *bh; befs_sb_info *befs_sb; befs_super_block *disk_sb; struct inode *root; long ret = -EINVAL; const unsigned long sb_block = 0; const off_t x86_sb_off = 512; save_mount_options(sb, data); sb->s_fs_info = kmalloc(sizeof (*befs_sb), GFP_KERNEL); if (sb->s_fs_info == NULL) { printk(KERN_ERR "BeFS(%s): Unable to allocate memory for private " "portion of superblock. Bailing.\n", sb->s_id); goto unacquire_none; } befs_sb = BEFS_SB(sb); memset(befs_sb, 0, sizeof(befs_sb_info)); if (!parse_options((char *) data, &befs_sb->mount_opts)) { befs_error(sb, "cannot parse mount options"); goto unacquire_priv_sbp; } befs_debug(sb, "---> befs_fill_super()"); #ifndef CONFIG_BEFS_RW if (!(sb->s_flags & MS_RDONLY)) { befs_warning(sb, "No write support. Marking filesystem read-only"); sb->s_flags |= MS_RDONLY; } #endif /* CONFIG_BEFS_RW */ /* * Set dummy blocksize to read super block. * Will be set to real fs blocksize later. * * Linux 2.4.10 and later refuse to read blocks smaller than * the hardsect size for the device. But we also need to read at * least 1k to get the second 512 bytes of the volume. * -WD 10-26-01 */ sb_min_blocksize(sb, 1024); if (!(bh = sb_bread(sb, sb_block))) { befs_error(sb, "unable to read superblock"); goto unacquire_priv_sbp; } /* account for offset of super block on x86 */ disk_sb = (befs_super_block *) bh->b_data; if ((disk_sb->magic1 == BEFS_SUPER_MAGIC1_LE) || (disk_sb->magic1 == BEFS_SUPER_MAGIC1_BE)) { befs_debug(sb, "Using PPC superblock location"); } else { befs_debug(sb, "Using x86 superblock location"); disk_sb = (befs_super_block *) ((void *) bh->b_data + x86_sb_off); } if (befs_load_sb(sb, disk_sb) != BEFS_OK) goto unacquire_bh; befs_dump_super_block(sb, disk_sb); brelse(bh); if (befs_check_sb(sb) != BEFS_OK) goto unacquire_priv_sbp; if( befs_sb->num_blocks > ~((sector_t)0) ) { befs_error(sb, "blocks count: %Lu " "is larger than the host can use", befs_sb->num_blocks); goto unacquire_priv_sbp; } /* * set up enough so that it can read an inode * Fill in kernel superblock fields from private sb */ sb->s_magic = BEFS_SUPER_MAGIC; /* Set real blocksize of fs */ sb_set_blocksize(sb, (ulong) befs_sb->block_size); sb->s_op = &befs_sops; root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); if (IS_ERR(root)) { ret = PTR_ERR(root); goto unacquire_priv_sbp; } sb->s_root = d_make_root(root); if (!sb->s_root) { befs_error(sb, "get root inode failed"); goto unacquire_priv_sbp; } /* load nls library */ if (befs_sb->mount_opts.iocharset) { befs_debug(sb, "Loading nls: %s", befs_sb->mount_opts.iocharset); befs_sb->nls = load_nls(befs_sb->mount_opts.iocharset); if (!befs_sb->nls) { befs_warning(sb, "Cannot load nls %s" " loading default nls", befs_sb->mount_opts.iocharset); befs_sb->nls = load_nls_default(); } /* load default nls if none is specified in mount options */ } else { befs_debug(sb, "Loading default nls"); befs_sb->nls = load_nls_default(); } return 0; /*****************/ unacquire_bh: brelse(bh); unacquire_priv_sbp: kfree(befs_sb->mount_opts.iocharset); kfree(sb->s_fs_info); unacquire_none: sb->s_fs_info = NULL; return ret; }
/* Parse the (re)mount options */ static int parse_options(ntfs_volume* vol,char *opt) { char *value; vol->uid=vol->gid=0; vol->umask=0077; vol->ngt=ngt_nt; vol->nls_map=0; vol->nct=0; if(!opt)goto done; for(opt = strtok(opt,",");opt;opt=strtok(NULL,",")) { if ((value = strchr(opt, '=')) != NULL) *value++='\0'; if(strcmp(opt,"uid")==0) { if(!value || !*value)goto needs_arg; vol->uid=simple_strtoul(value,&value,0); if(*value){ printk(KERN_ERR "NTFS: uid invalid argument\n"); return 0; } }else if(strcmp(opt, "gid") == 0) { if(!value || !*value)goto needs_arg; vol->gid=simple_strtoul(value,&value,0); if(*value){ printk(KERN_ERR "gid invalid argument\n"); return 0; } }else if(strcmp(opt, "umask") == 0) { if(!value || !*value)goto needs_arg; vol->umask=simple_strtoul(value,&value,0); if(*value){ printk(KERN_ERR "umask invalid argument\n"); return 0; } }else if(strcmp(opt, "iocharset") == 0){ if(!value || !*value)goto needs_arg; vol->nls_map=load_nls(value); vol->nct |= nct_map; if(!vol->nls_map){ printk(KERN_ERR "NTFS: charset not found"); return 0; } }else if(strcmp(opt, "posix") == 0){ int val; if(!value || !*value)goto needs_arg; if(!simple_getbool(value,&val)) goto needs_bool; vol->ngt=val?ngt_posix:ngt_nt; }else if(strcmp(opt,"utf8") == 0){ int val=0; if(!value || !*value) val=1; else if(!simple_getbool(value,&val)) goto needs_bool; if(val) vol->nct|=nct_utf8; }else if(strcmp(opt,"uni_xlate") == 0){ int val=0; /* no argument: uni_vfat. boolean argument: uni_vfat. "2": uni. */ if(!value || !*value) val=1; else if(strcmp(value,"2")==0) vol->nct |= nct_uni_xlate; else if(!simple_getbool(value,&val)) goto needs_bool; if(val) vol->nct |= nct_uni_xlate_vfat | nct_uni_xlate; }else{ printk(KERN_ERR "NTFS: unkown option '%s'\n", opt); return 0; } } if(vol->nct & nct_utf8 & (nct_map | nct_uni_xlate)){ printk(KERN_ERR "utf8 cannot be combined with iocharset or uni_xlate\n"); return 0; } done: if((vol->nct & (nct_uni_xlate | nct_map | nct_utf8))==0) /* default to UTF-8 */ vol->nct=nct_utf8; if(!vol->nls_map){ vol->nls_map=load_nls_default(); if (vol->nls_map) vol->nct=nct_map | (vol->nct&nct_uni_xlate); } return 1; needs_arg: printk(KERN_ERR "NTFS: %s needs an argument",opt); return 0; needs_bool: printk(KERN_ERR "NTFS: %s needs boolean argument",opt); return 0; }
/* * NAME: DriverEntry * FUNCTION: Called by the system to initalize the driver * * ARGUMENTS: * DriverObject = object describing this driver * RegistryPath = path to our configuration entries * RETURNS: Success or failure */ NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { PDEVICE_OBJECT DiskdevObject = NULL; PDEVICE_OBJECT CdromdevObject = NULL; UNICODE_STRING DeviceName; UNICODE_STRING DosDeviceName; PFAST_IO_DISPATCH FastIoDispatch; PCACHE_MANAGER_CALLBACKS CacheManagerCallbacks; NTSTATUS Status; int rc = 0; BOOLEAN linux_lib_inited = FALSE; BOOLEAN journal_module_inited = FALSE; /* Verity super block ... */ ASSERT(sizeof(EXT2_SUPER_BLOCK) == 1024); ASSERT(FIELD_OFFSET(EXT2_SUPER_BLOCK, s_magic) == 56); DbgPrint( "Ext2Fsd --" #ifdef _WIN2K_TARGET_ " Win2k --" #endif " Version " EXT2FSD_VERSION #if EXT2_DEBUG " Checked" #else " Free" #endif " -- " __DATE__ " " __TIME__ ".\n"); DEBUG(DL_FUN, ( "Ext2 DriverEntry ...\n")); /* initialize winlib structures */ if (ext2_init_linux()) { Status = STATUS_INSUFFICIENT_RESOURCES; goto errorout; } linux_lib_inited = TRUE; /* initialize journal module structures */ LOAD_MODULE(journal_init); if (rc != 0) { Status = STATUS_INSUFFICIENT_RESOURCES; goto errorout; } journal_module_inited = TRUE; /* allocate memory for Ext2Global */ Ext2Global = Ext2AllocatePool(NonPagedPool, sizeof(EXT2_GLOBAL), 'LG2E'); if (!Ext2Global) { Status = STATUS_INSUFFICIENT_RESOURCES; goto errorout; } /* initialize Ext2Global */ RtlZeroMemory(Ext2Global, sizeof(EXT2_GLOBAL)); Ext2Global->Identifier.Type = EXT2FGD; Ext2Global->Identifier.Size = sizeof(EXT2_GLOBAL); InitializeListHead(&(Ext2Global->VcbList)); ExInitializeResourceLite(&(Ext2Global->Resource)); /* query registry settings */ Ext2QueryRegistrySettings(RegistryPath); /* create Ext2Fsd cdrom fs deivce */ RtlInitUnicodeString(&DeviceName, CDROM_NAME); Status = IoCreateDevice( DriverObject, 0, &DeviceName, FILE_DEVICE_CD_ROM_FILE_SYSTEM, 0, FALSE, &CdromdevObject ); if (!NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "IoCreateDevice cdrom device object error.\n")); goto errorout; } /* create Ext2Fsd disk fs deivce */ RtlInitUnicodeString(&DeviceName, DEVICE_NAME); Status = IoCreateDevice( DriverObject, 0, &DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &DiskdevObject ); if (!NT_SUCCESS(Status)) { DEBUG(DL_ERR, ( "IoCreateDevice disk device object error.\n")); goto errorout; } Status= Ext2StartReaper( &Ext2Global->FcbReaper, Ext2FcbReaperThread); if (!NT_SUCCESS(Status)) { goto errorout; } /* start resource reaper thread */ Status= Ext2StartReaper( &Ext2Global->McbReaper, Ext2McbReaperThread); if (!NT_SUCCESS(Status)) { Ext2StopReaper(&Ext2Global->FcbReaper); goto errorout; } Status= Ext2StartReaper( &Ext2Global->bhReaper, Ext2bhReaperThread); if (!NT_SUCCESS(Status)) { Ext2StopReaper(&Ext2Global->FcbReaper); Ext2StopReaper(&Ext2Global->McbReaper); goto errorout; } /* initializing */ Ext2Global->DiskdevObject = DiskdevObject; Ext2Global->CdromdevObject = CdromdevObject; DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_READ] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = Ext2BuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Ext2BuildRequest; #if (_WIN32_WINNT >= 0x0500) DriverObject->MajorFunction[IRP_MJ_PNP] = Ext2BuildRequest; #endif //(_WIN32_WINNT >= 0x0500) #if EXT2_UNLOAD DriverObject->DriverUnload = DriverUnload; #else DriverObject->DriverUnload = NULL; #endif // // Initialize the fast I/O entry points // FastIoDispatch = &(Ext2Global->FastIoDispatch); FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); FastIoDispatch->FastIoCheckIfPossible = Ext2FastIoCheckIfPossible; FastIoDispatch->FastIoRead = Ext2FastIoRead; FastIoDispatch->FastIoWrite = Ext2FastIoWrite; FastIoDispatch->FastIoQueryBasicInfo = Ext2FastIoQueryBasicInfo; FastIoDispatch->FastIoQueryStandardInfo = Ext2FastIoQueryStandardInfo; FastIoDispatch->FastIoLock = Ext2FastIoLock; FastIoDispatch->FastIoUnlockSingle = Ext2FastIoUnlockSingle; FastIoDispatch->FastIoUnlockAll = Ext2FastIoUnlockAll; FastIoDispatch->FastIoUnlockAllByKey = Ext2FastIoUnlockAllByKey; FastIoDispatch->FastIoQueryNetworkOpenInfo = Ext2FastIoQueryNetworkOpenInfo; FastIoDispatch->AcquireForModWrite = Ext2AcquireFileForModWrite; FastIoDispatch->ReleaseForModWrite = Ext2ReleaseFileForModWrite; FastIoDispatch->AcquireForModWrite = Ext2AcquireFileForModWrite; FastIoDispatch->ReleaseForModWrite = Ext2ReleaseFileForModWrite; FastIoDispatch->AcquireForCcFlush = Ext2AcquireFileForCcFlush; FastIoDispatch->ReleaseForCcFlush = Ext2ReleaseFileForCcFlush; FastIoDispatch->AcquireFileForNtCreateSection = Ext2AcquireForCreateSection; FastIoDispatch->ReleaseFileForNtCreateSection = Ext2ReleaseForCreateSection; DriverObject->FastIoDispatch = FastIoDispatch; // // initializing structure sizes for statistics // 1 means flexible/not fixed for all allocations (for different volumes). // Ext2Global->PerfStat.Magic = EXT2_PERF_STAT_MAGIC; Ext2Global->PerfStat.Version = EXT2_PERF_STAT_VER2; Ext2Global->PerfStat.Length = sizeof(EXT2_PERF_STATISTICS_V2); Ext2Global->PerfStat.Unit.Slot[PS_IRP_CONTEXT] = sizeof(EXT2_IRP_CONTEXT); /* 0 */ Ext2Global->PerfStat.Unit.Slot[PS_VCB] = sizeof(EXT2_VCB); /* 1 */ Ext2Global->PerfStat.Unit.Slot[PS_FCB] = sizeof(EXT2_FCB); /* 2 */ Ext2Global->PerfStat.Unit.Slot[PS_CCB] = sizeof(EXT2_CCB); /* 3 */ Ext2Global->PerfStat.Unit.Slot[PS_MCB] = sizeof(EXT2_MCB); /* 4 */ Ext2Global->PerfStat.Unit.Slot[PS_EXTENT] = sizeof(EXT2_EXTENT); /* 5 */ Ext2Global->PerfStat.Unit.Slot[PS_RW_CONTEXT] = sizeof(EXT2_RW_CONTEXT); /* 6 */ Ext2Global->PerfStat.Unit.Slot[PS_VPB] = sizeof(VPB); /* 7 */ Ext2Global->PerfStat.Unit.Slot[PS_FILE_NAME] = 1; /* 8 */ Ext2Global->PerfStat.Unit.Slot[PS_MCB_NAME] = 1; /* 9 */ Ext2Global->PerfStat.Unit.Slot[PS_INODE_NAME] = 1; /* a */ Ext2Global->PerfStat.Unit.Slot[PS_DIR_ENTRY] = sizeof(EXT2_DIR_ENTRY2); /* b */ Ext2Global->PerfStat.Unit.Slot[PS_DIR_PATTERN] = 1; /* c */ Ext2Global->PerfStat.Unit.Slot[PS_DISK_EVENT] = sizeof(KEVENT); /* d */ Ext2Global->PerfStat.Unit.Slot[PS_DISK_BUFFER] = 1; /* e */ Ext2Global->PerfStat.Unit.Slot[PS_BLOCK_DATA] = 1; /* f */ Ext2Global->PerfStat.Unit.Slot[PS_EXT2_INODE] = 1; /* 10 */ Ext2Global->PerfStat.Unit.Slot[PS_DENTRY] = sizeof(struct dentry); /* 11 */ Ext2Global->PerfStat.Unit.Slot[PS_BUFF_HEAD] = sizeof(struct buffer_head); /* 12 */ switch ( MmQuerySystemSize() ) { case MmSmallSystem: Ext2Global->MaxDepth = 64; break; case MmMediumSystem: Ext2Global->MaxDepth = 128; break; case MmLargeSystem: Ext2Global->MaxDepth = 256; break; } // // Initialize the Cache Manager callbacks // CacheManagerCallbacks = &(Ext2Global->CacheManagerCallbacks); CacheManagerCallbacks->AcquireForLazyWrite = Ext2AcquireForLazyWrite; CacheManagerCallbacks->ReleaseFromLazyWrite = Ext2ReleaseFromLazyWrite; CacheManagerCallbacks->AcquireForReadAhead = Ext2AcquireForReadAhead; CacheManagerCallbacks->ReleaseFromReadAhead = Ext2ReleaseFromReadAhead; Ext2Global->CacheManagerNoOpCallbacks.AcquireForLazyWrite = Ext2NoOpAcquire; Ext2Global->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = Ext2NoOpRelease; Ext2Global->CacheManagerNoOpCallbacks.AcquireForReadAhead = Ext2NoOpAcquire; Ext2Global->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = Ext2NoOpRelease; #ifndef _WIN2K_TARGET_ // // Initialize FS Filter callbacks // RtlZeroMemory(&Ext2Global->FilterCallbacks, sizeof(FS_FILTER_CALLBACKS)); Ext2Global->FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); Ext2Global->FilterCallbacks.PreAcquireForSectionSynchronization = Ext2PreAcquireForCreateSection; FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &Ext2Global->FilterCallbacks ); #endif // // Initialize the global data // ExInitializeNPagedLookasideList( &(Ext2Global->Ext2IrpContextLookasideList), NULL, NULL, 0, sizeof(EXT2_IRP_CONTEXT), 'PRIE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2FcbLookasideList), NULL, NULL, 0, sizeof(EXT2_FCB), 'BCFE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2CcbLookasideList), NULL, NULL, 0, sizeof(EXT2_CCB), 'BCCE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2McbLookasideList), NULL, NULL, 0, sizeof(EXT2_MCB), 'BCME', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2ExtLookasideList), NULL, NULL, 0, sizeof(EXT2_EXTENT), 'STXE', 0 ); ExInitializeNPagedLookasideList( &(Ext2Global->Ext2DentryLookasideList), NULL, NULL, 0, sizeof(struct dentry), 'TNED', 0 ); RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME); IoCreateSymbolicLink(&DosDeviceName, &DeviceName); #if EXT2_DEBUG ProcessNameOffset = Ext2GetProcessNameOffset(); #endif Ext2LoadAllNls(); Ext2Global->Codepage.PageTable = load_nls(Ext2Global->Codepage.AnsiName); /* register file system devices for disk and cdrom */ IoRegisterFileSystem(DiskdevObject); ObReferenceObject(DiskdevObject); IoRegisterFileSystem(CdromdevObject); ObReferenceObject(CdromdevObject); errorout: if (!NT_SUCCESS(Status)) { /* * stop reaper thread ... */ /* * cleanup resources ... */ if (Ext2Global) { ExDeleteResourceLite(&Ext2Global->Resource); Ext2FreePool(Ext2Global, 'LG2E'); } if (CdromdevObject) { IoDeleteDevice(CdromdevObject); } if (DiskdevObject) { IoDeleteDevice(DiskdevObject); } if (journal_module_inited) { /* cleanup journal related caches */ UNLOAD_MODULE(journal_exit); } if (linux_lib_inited) { /* cleanup linux lib */ ext2_destroy_linux(); } } return Status; }
/* allocate global info, try to map host share */ static int sf_glob_alloc(struct vbsf_mount_info_new *info, struct sf_glob_info **sf_gp) { int err, rc; SHFLSTRING *str_name; size_t name_len, str_len; struct sf_glob_info *sf_g; TRACE(); sf_g = kmalloc(sizeof(*sf_g), GFP_KERNEL); if (!sf_g) { err = -ENOMEM; LogRelFunc(("could not allocate memory for global info\n")); goto fail0; } RT_ZERO(*sf_g); if ( info->nullchar != '\0' || info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0 || info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1 || info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2) { /* An old version of mount.vboxsf made the syscall. Translate the * old parameters to the new structure. */ struct vbsf_mount_info_old *info_old = (struct vbsf_mount_info_old *)info; static struct vbsf_mount_info_new info_compat; info = &info_compat; memset(info, 0, sizeof(*info)); memcpy(&info->name, &info_old->name, MAX_HOST_NAME); memcpy(&info->nls_name, &info_old->nls_name, MAX_NLS_NAME); info->length = offsetof(struct vbsf_mount_info_new, dmode); info->uid = info_old->uid; info->gid = info_old->gid; info->ttl = info_old->ttl; } info->name[sizeof(info->name) - 1] = 0; info->nls_name[sizeof(info->nls_name) - 1] = 0; name_len = strlen(info->name); if (name_len > 0xfffe) { err = -ENAMETOOLONG; LogFunc(("map name too big\n")); goto fail1; } str_len = offsetof(SHFLSTRING, String.utf8) + name_len + 1; str_name = kmalloc(str_len, GFP_KERNEL); if (!str_name) { err = -ENOMEM; LogRelFunc(("could not allocate memory for host name\n")); goto fail1; } str_name->u16Length = name_len; str_name->u16Size = name_len + 1; memcpy(str_name->String.utf8, info->name, name_len + 1); #define _IS_UTF8(_str) \ (strcmp(_str, "utf8") == 0) #define _IS_EMPTY(_str) \ (strcmp(_str, "") == 0) /* Check if NLS charset is valid and not points to UTF8 table */ if (info->nls_name[0]) { if (_IS_UTF8(info->nls_name)) sf_g->nls = NULL; else { sf_g->nls = load_nls(info->nls_name); if (!sf_g->nls) { err = -EINVAL; LogFunc(("failed to load nls %s\n", info->nls_name)); goto fail1; } } } else { #ifdef CONFIG_NLS_DEFAULT /* If no NLS charset specified, try to load the default * one if it's not points to UTF8. */ if (!_IS_UTF8(CONFIG_NLS_DEFAULT) && !_IS_EMPTY(CONFIG_NLS_DEFAULT)) sf_g->nls = load_nls_default(); else sf_g->nls = NULL; #else sf_g->nls = NULL; #endif #undef _IS_UTF8 #undef _IS_EMPTY } rc = VbglR0SfMapFolder(&client_handle, str_name, &sf_g->map); kfree(str_name); if (RT_FAILURE(rc)) { err = -EPROTO; LogFunc(("VbglR0SfMapFolder failed rc=%d\n", rc)); goto fail2; } sf_g->ttl = info->ttl; sf_g->uid = info->uid; sf_g->gid = info->gid; if ((unsigned)info->length >= sizeof(struct vbsf_mount_info_new)) { /* new fields */ sf_g->dmode = info->dmode; sf_g->fmode = info->fmode; sf_g->dmask = info->dmask; sf_g->fmask = info->fmask; } else { sf_g->dmode = ~0; sf_g->fmode = ~0; } *sf_gp = sf_g; return 0; fail2: if (sf_g->nls) unload_nls(sf_g->nls); fail1: kfree(sf_g); fail0: return err; }