Jump to content

API: NtCreatePagingFile


Recommended Posts

Hi,

Someone could tell me how to change the pagefile using the API: NtCreatePagingFile SetSystemFileCacheSize

I need to use in my project: WinOnCD (LiveXP) and when I finish the project, I'll post all the source code, I thank everyone who help me.

I tried several times but without success... Below is the code I'm trying:

#include <Constants.au3>
#include <SecurityConstants.au3>

; Get total memory
Local $aTotalRAM = MemGetStats()
Local $iCacheSize = Int(($aTotalRAM[1] / 2) * 1024) ; in bytes

;#ifndef FILE_CACHE_FLAGS_DEFINED
Local $FILE_CACHE_MAX_HARD_ENABLE = 0x00000001
Local $FILE_CACHE_MAX_HARD_DISABLE = 0x00000002
Local $FILE_CACHE_MIN_HARD_ENABLE = 0x00000004
Local $FILE_CACHE_MIN_HARD_DISABLE = 0x00000008
;
Local $aPrivilege[2] = [$SE_INCREASE_QUOTA_NAME, $SE_PRIVILEGE_ENABLED]
_SetPrivilege($aPrivilege)

$pMinSize = DllStructCreate("int")
$pMaxSize = DllStructCreate("int")
DllStructSetData($pMinSize, 1, $iCacheSize)
DllStructSetData($pMaxSize, 1, $iCacheSize)

#cs
BOOL WINAPI SetSystemFileCacheSize(
  __in  SIZE_T MinimumFileCacheSize,
  __in  SIZE_T MaximumFileCacheSize,
  __in  DWORD Flags
);
#ce
$Kernel32 = "Kernel32.dll"
$aRet = DllCall($Kernel32, "BOOL", "SetSystemFileCacheSize", _
        "ptr", DllStructGetPtr($pMinSize), _
        "ptr", DllStructGetPtr($pMaxSize), _
        "DWORD", 0)

Local $aPrivilege[2] = [$SE_INCREASE_QUOTA_NAME, $SE_PRIVILEGE_REMOVED]
_SetPrivilege($aPrivilege)

MsgBox(4096, "Teste", $aRet[0])

; #FUNCTION# ====================================================================================================================================
; Name...........: _SetPrivilege
; Description ...: Enables or disables special privileges as required by some DllCalls
; Syntax.........: _SetPrivilege($avPrivilege)
; Parameters ....: $avPrivilege - An array of privileges and respective attributes
;                                 $SE_PRIVILEGE_ENABLED - The function enables the privilege
;                                 $SE_PRIVILEGE_REMOVED - The privilege is removed from the list of privileges in the token
;                                 0 - The function disables the privilege
; Requirement(s).: None
; Return values .: Success - An array of modified privileges and their respective previous attribute state
;                  Failure - An empty array
;                            Sets @error
; Author ........: engine
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......;
; ===============================================================================================================================================
Func _SetPrivilege($avPrivilege)
    Local $iDim = UBound($avPrivilege, 0), $avPrevState[1][2]
    If Not ( $iDim <= 2 And UBound($avPrivilege, $iDim) = 2 ) Then Return SetError(1300, 0, $avPrevState)
    If $iDim = 1 Then
        Local $avTemp[1][2]
        $avTemp[0][0] = $avPrivilege[0]
        $avTemp[0][1] = $avPrivilege[1]
        $avPrivilege = $avTemp
        $avTemp = 0
    EndIf
    Local $k, $tagTP = "dword", $iTokens = UBound($avPrivilege, 1)
    Do
        $k += 1
        $tagTP &= ";dword;long;dword"
    Until $k = $iTokens
    Local $tCurrState, $tPrevState, $pPrevState, $tLUID, $hAdvapi32, $hKernel32, $ahGCP, $avOPT, $aiGLE
    $tCurrState = DLLStructCreate($tagTP)
    $tPrevState = DllStructCreate($tagTP)
    $pPrevState = DllStructGetPtr($tPrevState)
    $tLUID = DllStructCreate("dword;long")
    DLLStructSetData($tCurrState, 1, $iTokens)
    $hAdvapi32 = DllOpen("Advapi32.dll")
    For $i = 0 To $iTokens - 1
        DllCall( $hAdvapi32, "int", "LookupPrivilegeValue", _
            "str", "", _
            "str", $avPrivilege[$i][0], _
            "ptr", DllStructGetPtr($tLUID) )
        DLLStructSetData( $tCurrState, 3 * $i + 2, DllStructGetData($tLUID, 1) )
        DLLStructSetData( $tCurrState, 3 * $i + 3, DllStructGetData($tLUID, 2) )
        DLLStructSetData( $tCurrState, 3 * $i + 4, $avPrivilege[$i][1] )
    Next
    $hKernel32 = DllOpen("Kernel32.dll")
    $ahGCP = DllCall($hKernel32, "hwnd", "GetCurrentProcess")
    $avOPT = DllCall( $hAdvapi32, "int", "OpenProcessToken", _
        "hwnd", $ahGCP[0], _
        "dword", BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY), _
        "hwnd*", 0 )
    DllCall( $hAdvapi32, "int", "AdjustTokenPrivileges", _
        "hwnd", $avOPT[3], _
        "int", False, _
        "ptr", DllStructGetPtr($tCurrState), _
        "dword", DllStructGetSize($tCurrState), _
        "ptr", $pPrevState, _
        "dword*", 0 )
    $aiGLE = DllCall($hKernel32, "dword", "GetLastError")
    DllCall($hKernel32, "int", "CloseHandle", "hwnd", $avOPT[3])
    DllClose($hKernel32)
    Local $iCount = DllStructGetData($tPrevState, 1)
    If $iCount > 0 Then
        Local $pLUID, $avLPN, $tName, $avPrevState[$iCount][2]
        For $i = 0 To $iCount - 1
            $pLUID = $pPrevState + 12 * $i + 4
            $avLPN = DllCall( $hAdvapi32, "int", "LookupPrivilegeName", _
                "str", "", _
                "ptr", $pLUID, _
                "ptr", 0, _
                "dword*", 0 )
            $tName = DllStructCreate("char[" & $avLPN[4] & "]")
            DllCall( $hAdvapi32, "int", "LookupPrivilegeName", _
                "str", "", _
                "ptr", $pLUID, _
                "ptr", DllStructGetPtr($tName), _
                "dword*", DllStructGetSize($tName) )
            $avPrevState[$i][0] = DllStructGetData($tName, 1)
            $avPrevState[$i][1] = DllStructGetData($tPrevState, 3 * $i + 4)
        Next
    EndIf
    DllClose($hAdvapi32)
    Return SetError($aiGLE[0], 0, $avPrevState)
EndFunc ;==> _SetPrivilege
Reference: http://msdn.microsoft.com/en-us/library/aa965240%28VS.85%29.aspx

I edited the title again because the name of the API was wrong...

Thanks to AdmiralAlkex.

Edited by jscript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

Unless I missed something, this is all very confusing.

Why do you want to change the size of the file cache? Why are you repeatedly calling it PageFile when it has nothing to do with that? Are you really using Win XP x64?

Minimum supported client Windows Vista, Windows XP Professional x64 Edition

:blink:

Link to comment
Share on other sites

Unless I missed something, this is all very confusing.

Why do you want to change the size of the file cache? Why are you repeatedly calling it PageFile when it has nothing to do with that? Are you really using Win XP x64? :blink:

Oh, yes, I had not paid attention to this detail...

Well, actually I need to set the pagefile in Windows XP x32.

You know what API should I use?

Edited by jscript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

I found the following source code on the net:

static BOOL EnablePrivilege()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;

    // Get a token for this process.
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    // Get the LUID for the shutdown privilege.
    LookupPrivilegeValue(NULL, SE_CREATE_PAGEFILE_NAME, &tp.Privileges[0].Luid);

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, 0);
    DWORD ret = GetLastError();
    return ret == ERROR_SUCCESS;
}



...

    HMODULE hDLL = LoadLibrary("NTDLL.dll");
    NtCreatePagingFile pf = (NtCreatePagingFile)GetProcAddress(hDLL, "NtCreatePagingFile");
    if (!EnablePrivilege())
    {
        return 1;
    }

        WCHAR pagefile[MAX_PATH];
    TCHAR Disk[25];
    TCHAR Dir = FileName[2];

    FileName[2] = 0;
    QueryDosDevice(FileName, Disk, 25);
    FileName[2]=Dir;

    StringCbPrintfW(pagefile, MAX_PATH, L"%S\\%S",Disk, &FileName[3]);
    int len = lstrlenW(pagefile);

    ULARGE_INTEGER liMinSize;
    ULARGE_INTEGER liMaxSize;
    liMinSize.QuadPart = MinSize;
    liMaxSize.QuadPart = MaxSize;
    liMinSize.QuadPart *= (1024 * 1024);
    liMaxSize.QuadPart *= (1024 * 1024);

    UNICODE_STRING us;
    us.Buffer = pagefile;
    us.Length = (USHORT)(len*sizeof(WCHAR));
    us.MaximumLength = us.Length+sizeof(WCHAR);
    DWORD ret = pf(&us, &liMinSize, &liMaxSize, 0);
And
static VOID
SmCreatePagingFiles (VOID)
{
    UNICODE_STRING FileName;
    ULONG ulCurrentSize;

    /* FIXME: Read file names from registry */

    RtlInitUnicodeString (&FileName,
                          L"\\SystemRoot\\pagefile.sys");

    NtCreatePagingFile (&FileName,
                        50,
                        80,
                        &ulCurrentSize);
}

But I could not successfully translating this for AutoIt...

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

Seems like a simple registry change here:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

ValueName: PagingFiles

---

Tested and works -- reboot to take effect

RegWrite('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management', 'PagingFiles', 'REG_MULTI_SZ', @HomeDrive & '\Pagefile.sys 256 512')
Edited by ripdad

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Seems like a simple registry change here:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

ValueName: PagingFiles

Tested and works -- reboot to take effect

I need to change it without restarting the computer and I know it is possible: SetPageFile.exe

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

  • Developers

I need to change it without restarting the computer and I know it is possible: SetPageFile.exe

also from BartPE or from WinXP/Win7?

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Why not just use that tool and write a wrapper?

Simple: Knowing that there is an API to perform this function and knowing the high capacity of AutoIt, why use third party programs?

Edit1: Do not tell me to use WMI functions: in my opinion this is for those who can not know how to use the APIs that Windows offers or the language we use does not support the DLL calls!

Edit2: I used diskpart.exe and Subst.exe for exchange of drive letters and create virtual drives: do not need more, see -> _Drives (UDF)

Edited by jscript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

According to that it could be something like this:

Func _CreatePagingFiles($sPageFile, $iMiniumSize, $iMaxiumSize)
    Local Const $SE_CREATE_PAGEFILE_PRIVILEGE = 15
    DllCall("ntdll.dll", "int", "RtlAdjustPrivilege", "int", $SE_CREATE_PAGEFILE_PRIVILEGE, "boolean", 1, "boolean", 0, "boolean*", 0)
    If @error Then Return SetError(1, 0, 0)
    Local $aCall = DllCall("ntdll.dll", "int", "NtCreatePagingFile", "wstr", $sPageFile, "dword_ptr", $iMiniumSize, "dword_ptr", $iMaxiumSize, "dword_ptr*", 0)
    If @error Then
        DllCall("ntdll.dll", "int", "RtlAdjustPrivilege", "int", $SE_CREATE_PAGEFILE_PRIVILEGE, "boolean", 0, "boolean", 0, "boolean*", 0)
        Return SetError(2, 0, 0)
    EndIf
    DllCall("ntdll.dll", "int", "RtlAdjustPrivilege", "int", $SE_CREATE_PAGEFILE_PRIVILEGE, "boolean", 0, "boolean", 0, "boolean*", 0)
    Return $aCall[4]
EndFunc

Emphasizing 'could'.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Emphasizing 'could'.

Yes, but:

paraglider, Jan 27 2005 - 07:17 PM

dumpbin and looked at the file imports. Its not looking good so far. I think the file name pointer in the file name parameter is not a normal file as c:\pagefile.sys does not work.

I believe the page file has to be in the root of a drive and named pagefile.sys

I worked out what the format of the file name should be. Its \Device\HarddiskVolume1\pagefile.sys

where 1 = drive c, 2 = drive d etc.

To complete explanation: Page File, Virtual Ram, Pagefile.sys, creating a page file, is it possible?

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

You can obtain the MS-DOS device names with the function _WinAPI_QueryDosDevice() from Yashieds excellent WinAPIEx UDF.

Ok, but still did not work...

Thought:

Slowly I'm realizing that some Windows APIs are not documented beyond are also quite obscure., but these same APIs, I see examples in C++ that work fine, but to translate into AutoIt, there is great difficult ... is not that AutoIt complicated or not powerful, but is a little tricky in calls to DLLs, at least for me...

Even so, many thanks to all who tried to help me.

Edited by jscript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...