⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldr.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: ldr.c 25049 2006-12-03 21:06:03Z fireball $
 *
 * COPYRIGHT: See COPYING in the top level directory
 * PROJECT  : ReactOS user mode libraries
 * MODULE   : kernel32.dll
 * FILE     : reactos/lib/kernel32/misc/ldr.c
 * AUTHOR   : Ariadne
 */

#include <k32.h>

#define NDEBUG
#include "../include/debug.h"

typedef struct tagLOADPARMS32 {
  LPSTR lpEnvAddress;
  LPSTR lpCmdLine;
  LPSTR lpCmdShow;
  DWORD dwReserved;
} LOADPARMS32;

extern BOOLEAN InWindows;

/* FUNCTIONS ****************************************************************/

/**
 * @name GetDllLoadPath
 *
 * Internal function to compute the load path to use for a given dll.
 *
 * @remarks Returned pointer must be freed by caller.
 */

LPWSTR STDCALL
GetDllLoadPath(LPCWSTR lpModule)
{
        ULONG Pos = 0, Length = 0;
        PWCHAR EnvironmentBufferW = NULL;
        LPCWSTR lpModuleEnd = NULL;
        UNICODE_STRING ModuleName;

	if (lpModule != NULL)
	{
		lpModuleEnd = lpModule + wcslen(lpModule);
	}
	else
	{
	        ModuleName = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->ImagePathName;
	        lpModule = ModuleName.Buffer;
	        lpModuleEnd = lpModule + (ModuleName.Length / sizeof(WCHAR));
	}

	if (lpModule != NULL)
	{
	        while (lpModuleEnd > lpModule && *lpModuleEnd != L'/' &&
	               *lpModuleEnd != L'\\' && *lpModuleEnd != L':')
			--lpModuleEnd;
		Length = (lpModuleEnd - lpModule) + 1;
	}

	Length += GetCurrentDirectoryW(0, NULL);
	Length += GetSystemDirectoryW(NULL, 0);
	Length += GetWindowsDirectoryW(NULL, 0);
	Length += GetEnvironmentVariableW(L"PATH", NULL, 0);

	EnvironmentBufferW = RtlAllocateHeap(RtlGetProcessHeap(), 0,
                                             Length * sizeof(WCHAR));
	if (EnvironmentBufferW == NULL)
		return NULL;

	if (lpModule)
	{
		RtlCopyMemory(EnvironmentBufferW, lpModule,
		              (lpModuleEnd - lpModule) * sizeof(WCHAR));
		Pos += lpModuleEnd - lpModule;
		EnvironmentBufferW[Pos++] = L';';
	}
	Pos += GetCurrentDirectoryW(Length, EnvironmentBufferW + Pos);
	EnvironmentBufferW[Pos++] = L';';
	Pos += GetSystemDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
	EnvironmentBufferW[Pos++] = L';';
	Pos += GetWindowsDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
	EnvironmentBufferW[Pos++] = L';';
	Pos += GetEnvironmentVariableW(L"PATH", EnvironmentBufferW + Pos, Length - Pos);
	EnvironmentBufferW[Pos] = 0;

	return EnvironmentBufferW;
}

/*
 * @implemented
 */
BOOL
STDCALL
DisableThreadLibraryCalls (
	HMODULE	hLibModule
	)
{
	NTSTATUS Status;

	Status = LdrDisableThreadCalloutsForDll ((PVOID)hLibModule);
	if (!NT_SUCCESS (Status))
	{
		SetLastErrorByStatus (Status);
		return FALSE;
	}
	return TRUE;
}


/*
 * @implemented
 */
HINSTANCE
STDCALL
LoadLibraryA (
	LPCSTR	lpLibFileName
	)
{
	return LoadLibraryExA (lpLibFileName, 0, 0);
}


/*
 * @implemented
 */
HINSTANCE
STDCALL
LoadLibraryExA (
	LPCSTR	lpLibFileName,
	HANDLE	hFile,
	DWORD	dwFlags
	)
{
   PWCHAR FileNameW;

   if (!(FileNameW = FilenameA2W(lpLibFileName, FALSE)))
      return FALSE;

   return LoadLibraryExW(FileNameW, hFile, dwFlags);
}


/*
 * @implemented
 */
HINSTANCE
STDCALL
LoadLibraryW (
	LPCWSTR	lpLibFileName
	)
{
	return LoadLibraryExW (lpLibFileName, 0, 0);
}


/*
 * @implemented
 */
HINSTANCE
STDCALL
LoadLibraryExW (
	LPCWSTR	lpLibFileName,
	HANDLE	hFile,
	DWORD	dwFlags
	)
{
	UNICODE_STRING DllName;
	HINSTANCE hInst;
	NTSTATUS Status;
	PWSTR SearchPath;
    ULONG DllCharacteristics;

        (void)hFile;

	if ( lpLibFileName == NULL )
		return NULL;

    /* Check for any flags LdrLoadDll might be interested in */
    if (dwFlags & DONT_RESOLVE_DLL_REFERENCES)
    {
        /* Tell LDR to treat it as an EXE */
        DllCharacteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
    }

	dwFlags &=
	  DONT_RESOLVE_DLL_REFERENCES |
	  LOAD_LIBRARY_AS_DATAFILE |
	  LOAD_WITH_ALTERED_SEARCH_PATH;

	SearchPath = GetDllLoadPath(
	  dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH ? lpLibFileName : NULL);

	RtlInitUnicodeString(&DllName, (LPWSTR)lpLibFileName);
    if (InWindows)
    {
        /* Call the API Properly */
        Status = LdrLoadDll(SearchPath,
                            &DllCharacteristics,
                            &DllName,
                            (PVOID*)&hInst);
    }
    else
    {
        /* Call the ROS API. NOTE: Don't fix this, I have a patch to merge later. */
        Status = LdrLoadDll(SearchPath, &dwFlags, &DllName, (PVOID*)&hInst);
    }
	RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
	if ( !NT_SUCCESS(Status))
	{
		SetLastErrorByStatus (Status);
		return NULL;
	}

	return hInst;
}


/*
 * @implemented
 */
FARPROC
STDCALL
GetProcAddress( HMODULE hModule, LPCSTR lpProcName )
{
	ANSI_STRING ProcedureName;
	FARPROC fnExp = NULL;

	if (HIWORD(lpProcName) != 0)
	{
		RtlInitAnsiString (&ProcedureName,
		                   (LPSTR)lpProcName);
		LdrGetProcedureAddress ((PVOID)hModule,
		                        &ProcedureName,
		                        0,
		                        (PVOID*)&fnExp);
	}
	else
	{
		LdrGetProcedureAddress ((PVOID)hModule,
		                        NULL,
		                        (ULONG)lpProcName,
		                        (PVOID*)&fnExp);
	}

	return fnExp;
}


/*
 * @implemented
 */
BOOL
STDCALL
FreeLibrary( HMODULE hLibModule )
{
	LdrUnloadDll(hLibModule);
	return TRUE;
}


/*
 * @implemented
 */
VOID
STDCALL
FreeLibraryAndExitThread (
	HMODULE	hLibModule,
	DWORD	dwExitCode
	)
{
	if ( FreeLibrary(hLibModule) )
		ExitThread(dwExitCode);
	for (;;)
		;
}


/*
 * @implemented
 */
DWORD
STDCALL
GetModuleFileNameA (
	HINSTANCE	hModule,
	LPSTR		lpFilename,
	DWORD		nSize
	)
{
	ANSI_STRING FileName;
	PLIST_ENTRY ModuleListHead;
	PLIST_ENTRY Entry;
	PLDR_DATA_TABLE_ENTRY Module;
	PPEB Peb;
	ULONG Length = 0;

	Peb = NtCurrentPeb ();
	RtlEnterCriticalSection (Peb->LoaderLock);

	if (hModule == NULL)
		hModule = Peb->ImageBaseAddress;

	ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
	Entry = ModuleListHead->Flink;

	while (Entry != ModuleListHead)
	{
		Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
		if (Module->DllBase == (PVOID)hModule)
		{
			if (nSize * sizeof(WCHAR) < Module->FullDllName.Length)
			{
				SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
			}
			else
			{
				FileName.Length = 0;
				FileName.MaximumLength = nSize * sizeof(WCHAR);
				FileName.Buffer = lpFilename;

				/* convert unicode string to ansi (or oem) */
				if (bIsFileApiAnsi)
					RtlUnicodeStringToAnsiString (&FileName,
					                              &Module->FullDllName,
					                              FALSE);
				else
					RtlUnicodeStringToOemString (&FileName,
					                             &Module->FullDllName,
					                             FALSE);
				Length = Module->FullDllName.Length / sizeof(WCHAR);
			}

			RtlLeaveCriticalSection (Peb->LoaderLock);
			return Length;
		}

		Entry = Entry->Flink;
	}

	SetLastErrorByStatus (STATUS_DLL_NOT_FOUND);
	RtlLeaveCriticalSection (Peb->LoaderLock);

	return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -