2000-03-12 23:28:59 +00:00
|
|
|
/* $Id: dirwr.c,v 1.10 2000/03/12 23:28:59 ekohl Exp $
|
2000-03-01 23:41:35 +00:00
|
|
|
*
|
1999-01-13 15:25:50 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: services/fs/vfat/dirwr.c
|
|
|
|
* PURPOSE: VFAT Filesystem : write in directory
|
2000-03-12 23:28:59 +00:00
|
|
|
*
|
|
|
|
*/
|
1999-01-13 15:25:50 +00:00
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
2000-02-21 22:44:37 +00:00
|
|
|
#include <ddk/ntddk.h>
|
1999-03-19 05:55:55 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <wchar.h>
|
1999-01-13 15:25:50 +00:00
|
|
|
#include <internal/string.h>
|
|
|
|
|
1999-01-20 13:00:35 +00:00
|
|
|
#define NDEBUG
|
1999-01-13 15:25:50 +00:00
|
|
|
#include <internal/debug.h>
|
|
|
|
|
|
|
|
#include "vfat.h"
|
|
|
|
|
1999-03-19 05:55:55 +00:00
|
|
|
NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject)
|
1999-01-13 15:25:50 +00:00
|
|
|
/*
|
|
|
|
update an existing FAT entry
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
WCHAR DirName[MAX_PATH],*FileName,*PathFileName;
|
1999-12-11 21:14:49 +00:00
|
|
|
VFATFCB FileFcb;
|
1999-03-19 05:55:55 +00:00
|
|
|
ULONG Sector=0,Entry=0;
|
|
|
|
PUCHAR Buffer;
|
|
|
|
FATDirEntry * pEntries;
|
1999-01-13 15:25:50 +00:00
|
|
|
NTSTATUS status;
|
|
|
|
FILE_OBJECT FileObject;
|
1999-12-11 21:14:49 +00:00
|
|
|
PVFATCCB pDirCcb;
|
|
|
|
PVFATFCB pDirFcb,pFcb;
|
1999-01-13 15:25:50 +00:00
|
|
|
short i,posCar,NameLen;
|
1999-03-19 05:55:55 +00:00
|
|
|
PathFileName=pFileObject->FileName.Buffer;
|
1999-12-11 21:14:49 +00:00
|
|
|
pFcb=((PVFATCCB)pFileObject->FsContext2)->pFcb;
|
1999-01-13 15:25:50 +00:00
|
|
|
//find last \ in PathFileName
|
|
|
|
posCar=-1;
|
|
|
|
for(i=0;PathFileName[i];i++)
|
|
|
|
if(PathFileName[i]=='\\')posCar=i;
|
|
|
|
if(posCar==-1)
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
FileName=&PathFileName[posCar+1];
|
|
|
|
for(NameLen=0;FileName[NameLen];NameLen++);
|
|
|
|
// extract directory name from pathname
|
1999-01-20 13:00:35 +00:00
|
|
|
memcpy(DirName,PathFileName,posCar*sizeof(WCHAR));
|
1999-01-13 15:25:50 +00:00
|
|
|
DirName[posCar]=0;
|
|
|
|
if(FileName[0]==0 && DirName[0]==0)
|
|
|
|
return STATUS_SUCCESS;//root : nothing to do ?
|
1999-01-20 13:00:35 +00:00
|
|
|
memset(&FileObject,0,sizeof(FILE_OBJECT));
|
2000-01-12 19:05:32 +00:00
|
|
|
DPRINT("open directory %S for update of entry %S\n",DirName,FileName);
|
1999-01-13 15:25:50 +00:00
|
|
|
status=FsdOpenFile(DeviceExt,&FileObject,DirName);
|
1999-12-11 21:14:49 +00:00
|
|
|
pDirCcb=(PVFATCCB)FileObject.FsContext2;
|
1999-01-20 13:00:35 +00:00
|
|
|
assert(pDirCcb);
|
|
|
|
pDirFcb=pDirCcb->pFcb;
|
|
|
|
assert(pDirFcb);
|
1999-01-13 15:25:50 +00:00
|
|
|
FileFcb.ObjectName=&FileFcb.PathName[0];
|
1999-03-19 05:55:55 +00:00
|
|
|
status=FindFile(DeviceExt,&FileFcb,pDirFcb,FileName,&Sector,&Entry);
|
1999-01-20 13:00:35 +00:00
|
|
|
if(NT_SUCCESS(status))
|
|
|
|
{
|
1999-03-19 05:55:55 +00:00
|
|
|
Buffer=ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
|
|
|
DPRINT("update entry: sector %d, entry %d\n",Sector,Entry);
|
|
|
|
VFATReadSectors(DeviceExt->StorageDevice,Sector,1,Buffer);
|
|
|
|
pEntries=(FATDirEntry *)Buffer;
|
|
|
|
memcpy(&pEntries[Entry],&pFcb->entry,sizeof(FATDirEntry));
|
|
|
|
VFATWriteSectors(DeviceExt->StorageDevice,Sector,1,Buffer);
|
|
|
|
ExFreePool(Buffer);
|
1999-01-20 13:00:35 +00:00
|
|
|
}
|
1999-01-13 15:25:50 +00:00
|
|
|
FsdCloseFile(DeviceExt,&FileObject);
|
1999-01-20 13:00:35 +00:00
|
|
|
return status;
|
1999-01-13 15:25:50 +00:00
|
|
|
}
|
|
|
|
|
2000-03-12 23:28:59 +00:00
|
|
|
NTSTATUS addEntry(PDEVICE_EXTENSION DeviceExt,
|
|
|
|
PFILE_OBJECT pFileObject,
|
|
|
|
ULONG RequestedOptions,
|
|
|
|
UCHAR ReqAttr)
|
1999-01-13 15:25:50 +00:00
|
|
|
/*
|
|
|
|
create a new FAT entry
|
|
|
|
*/
|
|
|
|
{
|
2000-03-12 23:28:59 +00:00
|
|
|
WCHAR DirName[MAX_PATH],*FileName,*PathFileName;
|
|
|
|
VFATFCB DirFcb,FileFcb;
|
|
|
|
FATDirEntry FatEntry;
|
|
|
|
NTSTATUS status;
|
|
|
|
FILE_OBJECT FileObject;
|
|
|
|
FATDirEntry *pEntry;
|
|
|
|
slot *pSlots;
|
|
|
|
ULONG LengthRead,Offset;
|
|
|
|
short nbSlots=0,nbFree=0,i,j,posCar,NameLen;
|
|
|
|
PUCHAR Buffer,Buffer2;
|
|
|
|
BOOLEAN needTilde=FALSE,needLong=FALSE;
|
|
|
|
PVFATFCB newFCB;
|
|
|
|
PVFATCCB newCCB;
|
|
|
|
ULONG CurrentCluster;
|
1999-12-11 21:14:49 +00:00
|
|
|
KIRQL oldIrql;
|
2000-03-12 23:28:59 +00:00
|
|
|
LARGE_INTEGER SystemTime, LocalTime;
|
|
|
|
|
1999-01-13 15:25:50 +00:00
|
|
|
PathFileName=pFileObject->FileName.Buffer;
|
2000-01-12 19:05:32 +00:00
|
|
|
DPRINT("addEntry: Pathname=%S\n",PathFileName);
|
1999-01-13 15:25:50 +00:00
|
|
|
//find last \ in PathFileName
|
|
|
|
posCar=-1;
|
|
|
|
for(i=0;PathFileName[i];i++)
|
|
|
|
if(PathFileName[i]=='\\')posCar=i;
|
|
|
|
if(posCar==-1)
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
FileName=&PathFileName[posCar+1];
|
|
|
|
for(NameLen=0;FileName[NameLen];NameLen++);
|
|
|
|
// extract directory name from pathname
|
|
|
|
memcpy(DirName,PathFileName,posCar*sizeof(WCHAR));
|
|
|
|
DirName[posCar]=0;
|
1999-01-20 13:00:35 +00:00
|
|
|
// open parent directory
|
|
|
|
memset(&FileObject,0,sizeof(FILE_OBJECT));
|
1999-01-13 15:25:50 +00:00
|
|
|
status=FsdOpenFile(DeviceExt,&FileObject,DirName);
|
1999-01-20 13:00:35 +00:00
|
|
|
nbSlots=(NameLen+12)/13+1;//nb of entry needed for long name+normal entry
|
1999-01-13 15:25:50 +00:00
|
|
|
DPRINT("NameLen= %d, nbSlots =%d\n",NameLen,nbSlots);
|
|
|
|
Buffer=ExAllocatePool(NonPagedPool,(nbSlots+1)*sizeof(FATDirEntry));
|
|
|
|
memset(Buffer,0,(nbSlots+1)*sizeof(FATDirEntry));
|
|
|
|
pEntry=(FATDirEntry *)(Buffer+(nbSlots-1)*sizeof(FATDirEntry));
|
|
|
|
pSlots=(slot *)Buffer;
|
|
|
|
// create 8.3 name
|
|
|
|
needTilde=FALSE;
|
|
|
|
// find last point in name
|
|
|
|
posCar=0;
|
|
|
|
for(i=0;FileName[i];i++)
|
|
|
|
if(FileName[i]=='.')posCar=i;
|
|
|
|
if(!posCar) posCar=i;
|
|
|
|
if(posCar>8) needTilde=TRUE;
|
|
|
|
//copy 8 characters max
|
|
|
|
memset(pEntry,' ',11);
|
|
|
|
for(i=0,j=0;j<8 && i<posCar;i++)
|
|
|
|
{
|
1999-03-19 05:55:55 +00:00
|
|
|
//FIXME : is there other characters to ignore ?
|
1999-01-13 15:25:50 +00:00
|
|
|
if( FileName[i]!='.'
|
|
|
|
&& FileName[i]!=' '
|
|
|
|
&& FileName[i]!='+'
|
|
|
|
&& FileName[i]!=','
|
|
|
|
&& FileName[i]!=';'
|
|
|
|
&& FileName[i]!='='
|
|
|
|
&& FileName[i]!='['
|
|
|
|
&& FileName[i]!=']'
|
|
|
|
)
|
|
|
|
pEntry->Filename[j++]=toupper((char) FileName[i]);
|
|
|
|
else
|
|
|
|
needTilde=TRUE;
|
|
|
|
}
|
|
|
|
//copy extension
|
|
|
|
if(FileName[posCar])
|
1999-01-20 13:00:35 +00:00
|
|
|
for(j=0,i=posCar+1;FileName[i] && i<posCar+4;i++)
|
1999-01-13 15:25:50 +00:00
|
|
|
{
|
|
|
|
pEntry->Ext[j++]=toupper((char)( FileName[i] &0x7F));
|
|
|
|
}
|
1999-01-20 13:00:35 +00:00
|
|
|
if(FileName[i])
|
|
|
|
needTilde=TRUE;
|
1999-01-13 15:25:50 +00:00
|
|
|
//find good value for tilde
|
|
|
|
if(needTilde)
|
|
|
|
{
|
1999-01-20 13:00:35 +00:00
|
|
|
needLong=TRUE;
|
1999-01-13 15:25:50 +00:00
|
|
|
DPRINT("searching a good value for tilde\n");
|
|
|
|
for(i=0;i<6;i++)
|
|
|
|
DirName[i]=pEntry->Filename[i];
|
|
|
|
for(i=0;i<3;i++)
|
|
|
|
DirName[i+8]=pEntry->Ext[i];
|
|
|
|
//try first with xxxxxx~y.zzz
|
|
|
|
DirName[6]='~';
|
|
|
|
pEntry->Filename[6]='~';
|
|
|
|
DirName[8]='.';
|
|
|
|
DirName[12]=0;
|
|
|
|
for(i=1;i<9;i++)
|
|
|
|
{
|
|
|
|
DirName[7]='0'+i;
|
|
|
|
pEntry->Filename[7]='0'+i;
|
|
|
|
status=FindFile(DeviceExt,&FileFcb
|
1999-03-19 05:55:55 +00:00
|
|
|
,&DirFcb,DirName,NULL,NULL);
|
1999-01-13 15:25:50 +00:00
|
|
|
if(status!=STATUS_SUCCESS)break;
|
|
|
|
}
|
|
|
|
//try second with xxxxx~yy.zzz
|
|
|
|
if(i==10)
|
|
|
|
{
|
|
|
|
DirName[5]='~';
|
|
|
|
for( ;i<99;i++)
|
|
|
|
{
|
|
|
|
DirName[7]='0'+i;
|
|
|
|
pEntry->Filename[7]='0'+i;
|
|
|
|
status=FindFile(DeviceExt,&FileFcb
|
1999-03-19 05:55:55 +00:00
|
|
|
,&DirFcb,DirName,NULL,NULL);
|
1999-01-13 15:25:50 +00:00
|
|
|
if(status!=STATUS_SUCCESS)break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(i==100)//FIXME : what to do after 99 tilde ?
|
|
|
|
{
|
|
|
|
FsdCloseFile(DeviceExt,&FileObject);
|
|
|
|
ExFreePool(Buffer);
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
}
|
1999-01-20 13:00:35 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT("check if long name entry needed, needlong=%d\n",needLong);
|
|
|
|
for(i=0;i<posCar;i++)
|
|
|
|
if((USHORT)pEntry->Filename[i]!=FileName[i])
|
|
|
|
{
|
|
|
|
DPRINT("i=%d,%d,%d\n",i,pEntry->Filename[i],FileName[i]);
|
|
|
|
needLong=TRUE;
|
|
|
|
}
|
|
|
|
if(FileName[i])
|
|
|
|
{
|
|
|
|
i++;//jump on point char
|
|
|
|
for(j=0,i=posCar+1;FileName[i] && i<posCar+4;i++)
|
|
|
|
if((USHORT)pEntry->Ext[j++]!= FileName[i])
|
|
|
|
{
|
|
|
|
DPRINT("i=%d,j=%d,%d,%d\n",i,j,pEntry->Filename[i],FileName[i]);
|
|
|
|
needLong=TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(needLong==FALSE)
|
|
|
|
{
|
|
|
|
nbSlots=1;
|
|
|
|
memcpy(Buffer,pEntry,sizeof(FATDirEntry));
|
|
|
|
memset(pEntry,0,sizeof(FATDirEntry));
|
|
|
|
pEntry=(FATDirEntry *)Buffer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memset(DirName,0xff,sizeof(DirName));
|
|
|
|
memcpy(DirName,FileName,NameLen*sizeof(WCHAR));
|
|
|
|
DirName[NameLen]=0;
|
|
|
|
}
|
1999-01-13 15:25:50 +00:00
|
|
|
DPRINT("dos name=%11.11s\n",pEntry->Filename);
|
1999-01-20 13:00:35 +00:00
|
|
|
|
2000-03-12 23:28:59 +00:00
|
|
|
/* set attributes */
|
|
|
|
pEntry->Attrib=ReqAttr;
|
1999-01-13 15:25:50 +00:00
|
|
|
if(RequestedOptions&FILE_DIRECTORY_FILE)
|
|
|
|
pEntry->Attrib |= FILE_ATTRIBUTE_DIRECTORY;
|
2000-03-12 23:28:59 +00:00
|
|
|
|
|
|
|
/* set dates and times */
|
|
|
|
KeQuerySystemTime (&SystemTime);
|
|
|
|
ExSystemTimeToLocalTime (&SystemTime,
|
|
|
|
&LocalTime);
|
|
|
|
FsdFileTimeToDosDateTime ((TIME*)&LocalTime,
|
|
|
|
&pEntry->CreationDate,
|
|
|
|
&pEntry->CreationTime);
|
|
|
|
pEntry->UpdateDate = pEntry->CreationDate;
|
|
|
|
pEntry->UpdateTime = pEntry->CreationTime;
|
|
|
|
pEntry->AccessDate = pEntry->CreationDate;
|
|
|
|
|
1999-01-20 13:00:35 +00:00
|
|
|
// calculate checksum for 8.3 name
|
|
|
|
for(pSlots[0].alias_checksum=i=0;i<11;i++)
|
|
|
|
{
|
|
|
|
pSlots[0].alias_checksum=(((pSlots[0].alias_checksum&1)<<7
|
|
|
|
|((pSlots[0].alias_checksum&0xfe)>>1))
|
|
|
|
+pEntry->Filename[i]);
|
|
|
|
}
|
1999-01-13 15:25:50 +00:00
|
|
|
//construct slots and entry
|
|
|
|
for(i=nbSlots-2;i>=0;i--)
|
|
|
|
{
|
|
|
|
DPRINT("construct slot %d\n",i);
|
|
|
|
pSlots[i].attr=0xf;
|
|
|
|
if (i)
|
|
|
|
pSlots[i].id=nbSlots-i-1;
|
|
|
|
else
|
|
|
|
pSlots[i].id=nbSlots-i-1+0x40;
|
1999-01-20 13:00:35 +00:00
|
|
|
pSlots[i].alias_checksum=pSlots[0].alias_checksum;
|
|
|
|
//FIXME pSlots[i].start=;
|
1999-03-19 05:55:55 +00:00
|
|
|
memcpy(pSlots[i].name0_4 ,FileName+(nbSlots-i-2)*13
|
1999-01-13 15:25:50 +00:00
|
|
|
,5*sizeof(WCHAR));
|
1999-03-19 05:55:55 +00:00
|
|
|
memcpy(pSlots[i].name5_10 ,FileName+(nbSlots-i-2)*13+5
|
1999-01-13 15:25:50 +00:00
|
|
|
,6*sizeof(WCHAR));
|
1999-03-19 05:55:55 +00:00
|
|
|
memcpy(pSlots[i].name11_12,FileName+(nbSlots-i-2)*13+11
|
1999-01-13 15:25:50 +00:00
|
|
|
,2*sizeof(WCHAR));
|
|
|
|
}
|
2000-03-12 23:28:59 +00:00
|
|
|
|
1999-01-13 15:25:50 +00:00
|
|
|
//try to find nbSlots contiguous entries frees in directory
|
|
|
|
for(i=0,status=STATUS_SUCCESS;status==STATUS_SUCCESS;i++)
|
|
|
|
{
|
1999-03-19 05:55:55 +00:00
|
|
|
status=FsdReadFile(DeviceExt,&FileObject,&FatEntry
|
1999-01-13 15:25:50 +00:00
|
|
|
,sizeof(FATDirEntry),i*sizeof(FATDirEntry),&LengthRead);
|
1999-03-19 05:55:55 +00:00
|
|
|
if(IsLastEntry(&FatEntry,0))
|
1999-01-13 15:25:50 +00:00
|
|
|
break;
|
2000-03-12 23:28:59 +00:00
|
|
|
|
|
|
|
if(IsDeletedEntry(&FatEntry,0))
|
|
|
|
nbFree++;
|
|
|
|
else
|
|
|
|
nbFree=0;
|
|
|
|
|
|
|
|
if (nbFree==nbSlots)
|
|
|
|
break;
|
1999-01-13 15:25:50 +00:00
|
|
|
}
|
2000-03-12 23:28:59 +00:00
|
|
|
DPRINT("nbSlots %d nbFree %d, entry number %d\n",nbSlots,nbFree,i);
|
|
|
|
|
1999-01-20 13:00:35 +00:00
|
|
|
if(RequestedOptions&FILE_DIRECTORY_FILE)
|
1999-03-19 05:55:55 +00:00
|
|
|
{
|
1999-01-20 13:00:35 +00:00
|
|
|
CurrentCluster=GetNextWriteCluster(DeviceExt,0);
|
1999-03-19 05:55:55 +00:00
|
|
|
// zero the cluster
|
|
|
|
Buffer2=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
|
|
|
memset(Buffer2,0,DeviceExt->BytesPerCluster);
|
|
|
|
VFATWriteCluster(DeviceExt,Buffer2,CurrentCluster);
|
|
|
|
ExFreePool(Buffer2);
|
1999-01-20 13:00:35 +00:00
|
|
|
if (DeviceExt->FatType == FAT32)
|
|
|
|
{
|
|
|
|
pEntry->FirstClusterHigh=CurrentCluster>>16;
|
|
|
|
pEntry->FirstCluster=CurrentCluster;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pEntry->FirstCluster=CurrentCluster;
|
1999-01-13 15:25:50 +00:00
|
|
|
}
|
|
|
|
if(nbFree==nbSlots)
|
|
|
|
{//use old slots
|
|
|
|
Offset=(i-nbSlots+1)*sizeof(FATDirEntry);
|
1999-03-19 05:55:55 +00:00
|
|
|
status=FsdWriteFile(DeviceExt,&FileObject,Buffer
|
1999-01-13 15:25:50 +00:00
|
|
|
,sizeof(FATDirEntry)*nbSlots,Offset);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{//write at end of directory
|
|
|
|
Offset=(i-nbFree)*sizeof(FATDirEntry);
|
1999-03-19 05:55:55 +00:00
|
|
|
status=FsdWriteFile(DeviceExt,&FileObject,Buffer
|
1999-01-13 15:25:50 +00:00
|
|
|
,sizeof(FATDirEntry)*(nbSlots+1),Offset);
|
|
|
|
}
|
|
|
|
DPRINT("write entry offset %d status=%x\n",Offset,status);
|
1999-12-11 21:14:49 +00:00
|
|
|
newCCB = ExAllocatePool(NonPagedPool,sizeof(VFATCCB));
|
|
|
|
newFCB = ExAllocatePool(NonPagedPool,sizeof(VFATFCB));
|
|
|
|
memset(newCCB,0,sizeof(VFATCCB));
|
|
|
|
memset(newFCB,0,sizeof(VFATFCB));
|
1999-01-13 15:25:50 +00:00
|
|
|
newCCB->pFcb=newFCB;
|
|
|
|
newCCB->PtrFileObject=pFileObject;
|
|
|
|
newFCB->RefCount++;
|
1999-12-11 21:14:49 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* FIXME : initialize all fields in FCB and CCB
|
|
|
|
*/
|
|
|
|
KeAcquireSpinLock(&DeviceExt->FcbListLock, &oldIrql);
|
|
|
|
InsertTailList(&DeviceExt->FcbListHead, &newFCB->FcbListEntry);
|
|
|
|
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
|
|
|
|
|
|
|
|
|
1999-01-13 15:25:50 +00:00
|
|
|
memcpy(&newFCB->entry,pEntry,sizeof(FATDirEntry));
|
|
|
|
DPRINT("new : entry=%11.11s\n",newFCB->entry.Filename);
|
|
|
|
DPRINT("new : entry=%11.11s\n",pEntry->Filename);
|
|
|
|
vfat_wcsncpy(newFCB->PathName,PathFileName,MAX_PATH);
|
|
|
|
newFCB->ObjectName=newFCB->PathName+(PathFileName-FileName);
|
|
|
|
newFCB->pDevExt=DeviceExt;
|
|
|
|
pFileObject->FsContext =(PVOID) &newFCB->NTRequiredFCB;
|
|
|
|
pFileObject->FsContext2 = newCCB;
|
|
|
|
if(RequestedOptions&FILE_DIRECTORY_FILE)
|
|
|
|
{
|
|
|
|
// create . and ..
|
|
|
|
memcpy(pEntry->Filename,". ",11);
|
1999-03-19 05:55:55 +00:00
|
|
|
status=FsdWriteFile(DeviceExt,pFileObject,pEntry
|
1999-01-13 15:25:50 +00:00
|
|
|
,sizeof(FATDirEntry),0L);
|
|
|
|
pEntry->FirstCluster
|
1999-12-11 21:14:49 +00:00
|
|
|
=((VFATCCB *)(FileObject.FsContext2))->pFcb->entry.FirstCluster;
|
1999-01-13 15:25:50 +00:00
|
|
|
pEntry->FirstClusterHigh
|
1999-12-11 21:14:49 +00:00
|
|
|
=((VFATCCB *)(FileObject.FsContext2))->pFcb->entry.FirstClusterHigh;
|
1999-01-13 15:25:50 +00:00
|
|
|
memcpy(pEntry->Filename,".. ",11);
|
|
|
|
if(pEntry->FirstCluster==1 && DeviceExt->FatType!=FAT32)
|
|
|
|
pEntry->FirstCluster=0;
|
1999-03-19 05:55:55 +00:00
|
|
|
status=FsdWriteFile(DeviceExt,pFileObject,pEntry
|
1999-01-13 15:25:50 +00:00
|
|
|
,sizeof(FATDirEntry),sizeof(FATDirEntry));
|
|
|
|
}
|
|
|
|
FsdCloseFile(DeviceExt,&FileObject);
|
|
|
|
ExFreePool(Buffer);
|
|
|
|
DPRINT("addentry ok\n");
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-03-12 23:28:59 +00:00
|
|
|
/* EOF */
|