📄 name.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++
Module Name:
name.c
Abstract:
This file contains routines for manipulating FAT filenames.
Revision History:
--*/
#include "fatfs.h"
#define OEM_REPL_CHAR 0x5F
/* ChkSumName - compute 8.3 filename checksum
*
* ENTRY
* pchOEM - pointer to 8.3 filename
*
* EXIT
* 8-bit checksum. Note that it has to be computed the same way
* as all other LFN-enabled FAT file system implementations, because
* the checksum is stored on-disk.
*/
BYTE ChkSumName(const BYTE *pchOEM)
{
int c;
BYTE bSum = 0;
for (c = 0 ; c < OEMNAMESIZE ; ++c) {
bSum = (bSum>>1) | ((bSum&1)<<7);
bSum += *pchOEM++;
}
return bSum;
}
/* MatchesWildcard - compare filename to wildcard expression
*
* ENTRY
* lenWild - length of wildcard expression
* pchWild - pointer to wildcard expression
* lenFile - length of filename
* pchFile - pointer to filename
*
* EXIT
* TRUE if match, FALSE if not
*
* NOTES
* This code was taken straight from WINCE' object store
* implementation (ie, the same function exists in FILESYS.C)
*/
BOOL MatchesWildcard(DWORD lenWild, PCWSTR pchWild, DWORD lenFile, PCWSTR pchFile)
{
while (lenWild && lenFile) {
if (*pchWild == TEXTW('*')) {
pchWild++;
if (--lenWild) {
while (lenFile) {
if (MatchesWildcard(lenWild, pchWild, lenFile--, pchFile++))
return TRUE;
}
return FALSE;
}
return TRUE;
} else if ((*pchWild != TEXTW('?')) && _wcsnicmp(pchWild, pchFile, 1))
return FALSE;
lenWild--;
pchWild++;
lenFile--;
pchFile++;
}
if (!lenWild && !lenFile)
return TRUE;
if (!lenWild)
return FALSE;
else while (lenWild--) {
if (*pchWild++ != TEXTW('*'))
return FALSE;
}
return TRUE;
}
/* InitNumericTail - calculate starting position for numeric tail
*
* This function calculates the 0-based index in the 8.3 (achOEM) name
* of where the tilde (~) should go when creating a numeric tail for the
* name. The answer is always somewhere in the range 0-6, because the
* tilde is always followed by at least one digit (and as many as three).
*
* Note that we are starting with the hopeful assumption that the tail
* will require only one digit. If it requires two or three however, the
* code in CheckNumericTail and GenerateNumericTail may have to back up
* to insure the entire tail still fits within the 0-7 range.
*
* ENTRY
* pdi - pointer to DIRINFO structure
*
* EXIT
* None
*/
void InitNumericTail(PDIRINFO pdi)
{
int i, iSpace, cSpaces;
// We must walk forward through the single-byte character
// string, counting how many sequential spaces we have encountered,
// so that we can determine where the ideal spot for a numeric
// tail would be.
for (i=0,cSpaces=0; i<=6; i++) {
if (cSpaces == 0)
iSpace = i;
if (IsDBCSLeadByte(pdi->di_achOEM[i])) {
i++;
cSpaces = 0;
continue;
}
if (pdi->di_achOEM[i] != ' ') {
cSpaces = 0;
continue;
}
cSpaces++;
}
pdi->di_bNumericTail = (BYTE)iSpace;
}
/* CheckNumericTail - check 8.3 name for numeric tail
*
* This function examines the current directory entry, determines if
* it contains a numeric tail that could conflict with an auto-generated
* numeric tail, and flags it in our bit-array if so.
*
* ENTRY
* pdi - pointer to DIRINFO structure
* pdwBitArray - pointer to numeric tail bit array
*
* EXIT
* None
*/
void CheckNumericTail(PDIRINFO pdi, PDWORD pdwBitArray)
{
int i, iTilde, cDigits;
PCHAR pchComp;
BYTE achComp[OEMNAMESIZE];
ASSERT(pdi->di_bNumericTail <= 6);
// We must walk forward through the single-byte character
// string, and remember the position of the last tilde seen.
iTilde = -1;
for (i=0,pchComp=pdi->di_pde->de_name; i<=7; i++) {
if (IsDBCSLeadByte(pchComp[i])) {
i++;
iTilde = -1; // a DBCS char is never part of a tail
continue;
}
if (pchComp[i] == '~') {
if (i > pdi->di_bNumericTail || i < pdi->di_bNumericTail-2)
iTilde = -1; // this filename's tail is out of bounds
else {
iTilde = i;
cDigits = 0;
}
continue;
}
// cDigits, if used, will be validated when we call pchtoi(),
// so there's no need to verify this character really is a DIGIT.
if (iTilde != -1 && pchComp[i] != ' ')
cDigits++;
}
if (iTilde == -1 || cDigits == 0) {
// This name doesn't have a tail, so if we've already seen
// a match on the non-tail form, then we don't need to go any
// further.
if (TestBitArray(pdwBitArray, 0)) {
DEBUGMSGBREAK(!memcmp(pdi->di_achOEM, pdi->di_pde->de_name, sizeof(pdi->di_achOEM)), (DBGTEXT("FATFS!CheckNumericTail: non-tail form already exists!\n")));
return;
}
pchComp = pdi->di_achOEM;
cDigits = 0;
}
else {
// This name DOES have a tail...
memcpy(achComp, pdi->di_achOEM, sizeof(achComp));
memcpy(achComp+iTilde, pdi->di_pde->de_name+iTilde, cDigits+1);
pchComp = achComp;
}
if (memcmp(pchComp, pdi->di_pde->de_name, sizeof(achComp)) == 0) {
int v = 0;
if (cDigits) {
// Note that pchtoi() is unlike a typical atoi() function
// in that it doesn't simply return a converted integer
// when it reaches the first non-numeric character; if you
// tell it there should be cDigits digits, it INSISTS on
// that many digits.
v = pchtoi(pchComp+iTilde+1, cDigits);
// Check for "~0" (which we neither track nor generate)
// and non-numeric sequences (which pchtoi returns as -1).
if (v <= 0)
return;
}
// The directory is inconsistent if we find the same numeric
// tail more than once!
DEBUGMSGBREAK(TestBitArray(pdwBitArray, v), (DBGTEXT("FATFS!CheckNumericTail: %d already exists!\n"), v));
SetBitArray(pdwBitArray, v);
}
}
/* GenerateNumericTail - generate an 8.3 name with numeric tail
*
* ENTRY
* pdi - pointer to DIRINFO structure
* pdwBitArray - pointer to numeric tail bit array
*
* EXIT
* None
*
* NOTES
* Bit 0 of pdwBitArray corresponds to the unmodified/truncated 8.3
* version of the long filename, and bits 1-N correspond to names with
* numeric tails "~1" through "~N". A SET bit means that short name
* tail is in use, a CLEAR bit means it is available.
*/
void GenerateNumericTail(PDIRINFO pdi, PDWORD pdwBitArray)
{
if (!(pdi->di_flags & DIRINFO_OEM)) {
// Compare the number of SET bits to the TOTAL number of
// available bits; we add 1 to SET bits in case bit 0 is clear,
// because we're not currently interested in using that case.
if (pdwBitArray[1]+1 >= pdwBitArray[0]) {
// All the possibilities are in use, so just zero achOEM.
pdi->di_achOEM[0] = 0;
}
else {
int v;
// We know there's at least TWO clear bits (one of which may
// be bit 0). Find the next clear bit and create the corresponding
// numeric tail.
for (v=1; v < (int)pdwBitArray[0]; v++) {
if (!TestBitArray(pdwBitArray, v)) {
int i = pdi->di_bNumericTail;
if (v > 9) {
if (v <= 99) {
if (i > 5)
i = 5;
}
else if (v <= 999) {
if (i > 4)
i = 4;
}
else {
DEBUGMSGBREAK(TRUE, (DBGTEXT("FATFS!GenerateNumericTail: bit array too large! (%d)\n"), pdwBitArray[0]));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -