现在的位置: 首页 > 综合 > 正文

Windows API GetModuleFileName代码原型

2013年03月02日 ⁄ 综合 ⁄ 共 3344字 ⁄ 字号 评论关闭

以下是windows API GetModuleFileName的实现:

/*

 *@implemented

 */

DWORD WINAPI GetModuleFileNameA(HINSTANCEhModule,

                   LPSTR lpFilename,

                   DWORD nSize)

{

   UNICODE_STRING FilenameW;

   ANSI_STRING FilenameA;

   NTSTATUS Status;

   DWORD Length = 0, LengthToCopy;

 

   /* Allocate a unicode buffer */

   FilenameW.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nSize *sizeof(WCHAR));

   if (!FilenameW.Buffer)

    {

       BaseSetLastNTError(STATUS_NO_MEMORY);

       return 0;

    }

 

   /* Call unicode API */

   FilenameW.Length = GetModuleFileNameW(hModule, FilenameW.Buffer, nSize)* sizeof(WCHAR);

   FilenameW.MaximumLength = FilenameW.Length + sizeof(WCHAR);

 

   if (FilenameW.Length)

    {

       /* Convert to ansi string */

       Status = BasepUnicodeStringTo8BitString(&FilenameA, &FilenameW,TRUE);

       if (!NT_SUCCESS(Status))

       {

           /* Set last error, free string and retun failure */

           BaseSetLastNTError(Status);

            RtlFreeUnicodeString(&FilenameW);

           return 0;

       }

 

       /* Calculate size to copy */

       Length = min(nSize, FilenameA.Length);

 

       /* Include terminating zero */

       if (nSize > Length)

           LengthToCopy = Length + 1;

       else

           LengthToCopy = nSize;

 

       /* Now copy back to the caller amount he asked */

       RtlMoveMemory(lpFilename, FilenameA.Buffer, LengthToCopy);

 

       /* Free ansi filename */

       RtlFreeAnsiString(&FilenameA);

    }

 

   /* Free unicode filename */

   RtlFreeHeap(RtlGetProcessHeap(), 0, FilenameW.Buffer);

 

   /* Return length copied */

   return Length;

}

 

/*

 *@implemented

 */

DWORD WINAPI GetModuleFileNameW(HINSTANCEhModule,

                   LPWSTR lpFilename,

                   DWORD nSize)

{

    PLIST_ENTRY ModuleListHead, Entry;    //链表

   PLDR_DATA_TABLE_ENTRY Module;    //记录module的数据结构

   ULONG Length = 0;

   ULONG Cookie;

   PPEB Peb;

 

   hModule = BasepMapModuleHandle(hModule, FALSE);

 

   /* Upscale nSize from chars to bytes */

   nSize *= sizeof(WCHAR);

 

   _SEH2_TRY

    {

       /* We don't use per-thread cur dir now */

       //PRTL_PERTHREAD_CURDIR PerThreadCurdir =(PRTL_PERTHREAD_CURDIR)teb->NtTib.SubSystemTib;

 

       Peb = NtCurrentPeb ();

 

       /* Acquire a loader lock */

       LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL,&Cookie);

 

       /* Traverse the module list */

       ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;

       Entry = ModuleListHead->Flink;

       while (Entry != ModuleListHead)

       {

           Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);

 

           /* Check if this is the requested module */

           if (Module->DllBase == (PVOID)hModule)

           {

                /* Calculate size to copy */

                Length = min(nSize,Module->FullDllName.MaximumLength);

 

                /* Copy contents */

                RtlMoveMemory(lpFilename,Module->FullDllName.Buffer, Length);

 

                /* Subtract a terminating zero*/

                if (Length ==Module->FullDllName.MaximumLength)

                    Length -= sizeof(WCHAR);

 

                /* Break out of the loop */

                break;

           }

 

            /* Advance to the next entry */

           Entry = Entry->Flink;

       }

    }

   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

    {

       BaseSetLastNTError(_SEH2_GetExceptionCode());

       Length = 0;

    }_SEH2_END

 

   /* Release the loader lock */

   LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);

 

   return Length / sizeof(WCHAR);

}

从上可以看出Windows Module的数据都记录在PLDR_DATA_TABLE_ENTRY数据结构中,当要获取具体module名称的时候,会根据它的句柄,遍历整个链表,来获取相应的信息。

 

抱歉!评论已关闭.