Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
[pandora-kernel.git] / fs / cifs / cifssmb.c
index b004fef..7d14f24 100644 (file)
@@ -567,7 +567,7 @@ DelFileRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, 
+                   cifsConvertToUCS((__le16 *) pSMB->fileName, fileName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -665,7 +665,7 @@ MkDirRetry:
                return rc;
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-               name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, 
+               name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name, 
                                            PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -719,7 +719,7 @@ openRetry:
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                count = 1;      /* account for one byte pad to word boundary */
                name_len =
-                   cifsConvertToUCS((__u16 *) (pSMB->fileName + 1),
+                   cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
                                     fileName, PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -951,56 +951,69 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
 }
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
-int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
+int
+CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
             const int netfid, const unsigned int count,
-            const __u64 offset, unsigned int *nbytes, const char __user *buf,
+            const __u64 offset, unsigned int *nbytes, const char *buf,
             const int long_op)
 {
        int rc = -EACCES;
        WRITE_REQ *pSMB = NULL;
-       WRITE_RSP *pSMBr = NULL;
-       /*int bytes_returned;*/
-       unsigned bytes_sent;
+       int bytes_returned;
+       int smb_hdr_len;
+       __u32 bytes_sent;
        __u16 byte_count;
 
+       cERROR(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
        rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
-    
        if (rc)
                return rc;
-       
-       pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
-
        /* tcon and ses pointer are checked in smb_init */
        if (tcon->ses->server == NULL)
                return -ECONNABORTED;
 
-       pSMB->AndXCommand = 0xFF; /* none */
+       pSMB->AndXCommand = 0xFF;       /* none */
        pSMB->Fid = netfid;
        pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
        pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
        pSMB->Reserved = 0xFFFFFFFF;
        pSMB->WriteMode = 0;
        pSMB->Remaining = 0;
-       bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;
+
+       /* Can increase buffer size if buffer is big enough in some cases - ie 
+       can send more if LARGE_WRITE_X capability returned by the server and if
+       our buffer is big enough or if we convert to iovecs on socket writes
+       and eliminate the copy to the CIFS buffer */
+       if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
+               bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
+       } else {
+               bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
+                        & ~0xFF;
+       }
+
        if (bytes_sent > count)
                bytes_sent = count;
-       pSMB->DataLengthHigh = 0;
        pSMB->DataOffset =
            cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
 
-       byte_count = bytes_sent + 1 /* pad */ ;
-       pSMB->DataLengthLow = cpu_to_le16(bytes_sent);
-       pSMB->DataLengthHigh = 0;
-       pSMB->hdr.smb_buf_length += byte_count;
+       byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
+       pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
+       pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
+       smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
+       pSMB->hdr.smb_buf_length += bytes_sent+1;
        pSMB->ByteCount = cpu_to_le16(byte_count);
 
-/*     rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB,
-                        (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */  /* BB fixme BB */
+       rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len,
+                         buf, bytes_sent, &bytes_returned, long_op);
        if (rc) {
-               cFYI(1, ("Send error in write2 (large write) = %d", rc));
+               cFYI(1, ("Send error in write = %d", rc));
                *nbytes = 0;
-       } else
-               *nbytes = le16_to_cpu(pSMBr->Count);
+       } else {
+               WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
+               *nbytes = le16_to_cpu(pSMBr->CountHigh);
+               *nbytes = (*nbytes) << 16;
+               *nbytes += le16_to_cpu(pSMBr->Count);
+       }
 
        cifs_small_buf_release(pSMB);
 
@@ -1009,6 +1022,8 @@ int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 
        return rc;
 }
+
+
 #endif /* CIFS_EXPERIMENTAL */
 
 int
@@ -1141,7 +1156,7 @@ renameRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, 
+                   cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -1149,7 +1164,7 @@ renameRetry:
        /* protocol requires ASCII signature byte on Unicode string */
                pSMB->OldFileName[name_len + 1] = 0x00;
                name_len2 =
-                   cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2],
+                   cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2],
                                     toName, PATH_MAX, nls_codepage, remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
@@ -1236,10 +1251,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
        /* unicode only call */
        if(target_name == NULL) {
                sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
-               len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name,
+               len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
                                        dummy_string, 24, nls_codepage, remap);
        } else {
-               len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name,
+               len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
                                        target_name, PATH_MAX, nls_codepage, remap);
        }
        rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
@@ -1296,7 +1311,7 @@ copyRetry:
        pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-               name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, 
+               name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName, 
                                            fromName, PATH_MAX, nls_codepage,
                                            remap);
                name_len++;     /* trailing null */
@@ -1304,7 +1319,7 @@ copyRetry:
                pSMB->OldFileName[name_len] = 0x04;     /* pad */
                /* protocol requires ASCII signature byte on Unicode string */
                pSMB->OldFileName[name_len + 1] = 0x00;
-               name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 
+               name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 
                                toName, PATH_MAX, nls_codepage, remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
@@ -1453,7 +1468,7 @@ createHardLinkRetry:
                return rc;
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-               name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName,
+               name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName,
                                            PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -1476,7 +1491,7 @@ createHardLinkRetry:
        data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len_target =
-                   cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX,
+                   cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX,
                                     nls_codepage, remap);
                name_len_target++;      /* trailing null */
                name_len_target *= 2;
@@ -1546,14 +1561,14 @@ winCreateHardLinkRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName,
+                   cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
                pSMB->OldFileName[name_len] = 0;        /* pad */
                pSMB->OldFileName[name_len + 1] = 0x04; 
                name_len2 =
-                   cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 
+                   cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], 
                                     toName, PATH_MAX, nls_codepage, remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
@@ -1939,7 +1954,7 @@ queryAclRetry:
                                                                                                                                              
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+                       cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                         PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2024,7 +2039,7 @@ setAclRetry:
                return rc;
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+                       cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 
                                      PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2188,7 +2203,7 @@ QPathInfoRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2269,7 +2284,7 @@ UnixQPathInfoRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, searchName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
                                  PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2350,7 +2365,7 @@ findUniqueRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
                                  /* find define for this maxpathcomponent */
                                  , nls_codepage);
                name_len++;     /* trailing null */
@@ -2396,7 +2411,9 @@ findUniqueRetry:
        if (rc) {
                cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
        } else {                /* decode response */
-
+#ifdef CONFIG_CIFS_STATS
+               atomic_inc(&tcon->num_ffirst);
+#endif
                /* BB fill in */
        }
 
@@ -2414,7 +2431,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
              const char *searchName, 
              const struct nls_table *nls_codepage,
              __u16 *   pnetfid,
-             struct cifs_search_info * psrch_inf, int remap)
+             struct cifs_search_info * psrch_inf, int remap, const char dirsep)
 {
 /* level 257 SMB_ */
        TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -2435,13 +2452,13 @@ findFirstRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName,searchName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName,searchName,
                                 PATH_MAX, nls_codepage, remap);
                /* We can not add the asterik earlier in case
                it got remapped to 0xF03A as if it were part of the
                directory name instead of a wildcard */
                name_len *= 2;
-               pSMB->FileName[name_len] = '\\';
+               pSMB->FileName[name_len] = dirsep;
                pSMB->FileName[name_len+1] = 0;
                pSMB->FileName[name_len+2] = '*';
                pSMB->FileName[name_len+3] = 0;
@@ -2451,12 +2468,14 @@ findFirstRetry:
                name_len += 2;
        } else {        /* BB add check for overrun of SMB buf BB */
                name_len = strnlen(searchName, PATH_MAX);
-               name_len++;     /* trailing null */
 /* BB fix here and in unicode clause above ie
                if(name_len > buffersize-header)
                        free buffer exit; BB */
                strncpy(pSMB->FileName, searchName, name_len);
-               pSMB->FileName[name_len] = 0; /* just in case */
+               pSMB->FileName[name_len] = dirsep;
+               pSMB->FileName[name_len+1] = '*';
+               pSMB->FileName[name_len+2] = 0;
+               name_len += 3;
        }
 
        params = 12 + name_len /* includes null */ ;
@@ -2507,6 +2526,9 @@ findFirstRetry:
                if (rc == -EAGAIN)
                        goto findFirstRetry;
        } else { /* decode response */
+#ifdef CONFIG_CIFS_STATS
+               atomic_inc(&tcon->num_ffirst);
+#endif
                /* BB remember to free buffer if error BB */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
                if(rc == 0) {
@@ -2620,6 +2642,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
                } else
                        cFYI(1, ("FindNext returned = %d", rc));
        } else {                /* decode response */
+#ifdef CONFIG_CIFS_STATS
+               atomic_inc(&tcon->num_fnext);
+#endif
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
                
                if(rc == 0) {
@@ -2689,6 +2714,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
        if (rc) {
                cERROR(1, ("Send error in FindClose = %d", rc));
        }
+#ifdef CONFIG_CIFS_STATS
+       atomic_inc(&tcon->num_fclose);
+#endif
        cifs_small_buf_release(pSMB);
 
        /* Since session is dead, search handle closed on server already */
@@ -2724,7 +2752,7 @@ GetInodeNumberRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       cifsConvertToUCS((__u16 *) pSMB->FileName, searchName,
+                       cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
                                PATH_MAX,nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -2835,7 +2863,7 @@ getDFSRetry:
        if (ses->capabilities & CAP_UNICODE) {
                pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->RequestFileName,
+                   cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
                                     searchName, PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3252,6 +3280,77 @@ QFSUnixRetry:
        return rc;
 }
 
+int
+CIFSSMBSETFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
+{
+/* level 0x200  SMB_SET_CIFS_UNIX_INFO */
+       TRANSACTION2_SETFSI_REQ *pSMB = NULL;
+       TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
+       int rc = 0;
+       int bytes_returned = 0;
+       __u16 params, param_offset, offset, byte_count;
+
+       cFYI(1, ("In SETFSUnixInfo"));
+SETFSUnixRetry:
+       rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+                     (void **) &pSMBr);
+       if (rc)
+               return rc;
+
+       params = 4;     /* 2 bytes zero followed by info level. */
+       pSMB->MaxSetupCount = 0;
+       pSMB->Reserved = 0;
+       pSMB->Flags = 0;
+       pSMB->Timeout = 0;
+       pSMB->Reserved2 = 0;
+       param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4;
+       offset = param_offset + params;
+
+       pSMB->MaxParameterCount = cpu_to_le16(4);
+       pSMB->MaxDataCount = cpu_to_le16(100);  /* BB find exact max SMB PDU from sess structure BB */
+       pSMB->SetupCount = 1;
+       pSMB->Reserved3 = 0;
+       pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
+       byte_count = 1 /* pad */ + params + 12;
+
+       pSMB->DataCount = cpu_to_le16(12);
+       pSMB->ParameterCount = cpu_to_le16(params);
+       pSMB->TotalDataCount = pSMB->DataCount;
+       pSMB->TotalParameterCount = pSMB->ParameterCount;
+       pSMB->ParameterOffset = cpu_to_le16(param_offset);
+       pSMB->DataOffset = cpu_to_le16(offset);
+
+       /* Params. */
+       pSMB->FileNum = 0;
+       pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
+
+       /* Data. */
+       pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
+       pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
+       pSMB->ClientUnixCap = cpu_to_le64(cap);
+
+       pSMB->hdr.smb_buf_length += byte_count;
+       pSMB->ByteCount = cpu_to_le16(byte_count);
+
+       rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+       if (rc) {
+               cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
+       } else {                /* decode response */
+               rc = validate_t2((struct smb_t2_rsp *)pSMBr);
+               if (rc) {
+                       rc = -EIO;      /* bad smb */
+               }
+       }
+       cifs_buf_release(pSMB);
+
+       if (rc == -EAGAIN)
+               goto SETFSUnixRetry;
+
+       return rc;
+}
+
+
 
 int
 CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3367,7 +3466,7 @@ SetEOFRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3625,7 +3724,7 @@ SetTimesRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName,
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3706,7 +3805,7 @@ SetAttrLgcyRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                       ConvertToUCS((wchar_t *) pSMB->fileName, fileName, 
+                       ConvertToUCS((__le16 *) pSMB->fileName, fileName, 
                                PATH_MAX, nls_codepage);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3757,7 +3856,7 @@ setPermsRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -3902,7 +4001,7 @@ QAllEAsRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -4045,7 +4144,7 @@ QEARetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
@@ -4192,7 +4291,7 @@ SetEARetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 
+                   cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, 
                                     PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;