Jump to content
xYuri

[SOLVED] DllCall return 0 with Error 5

Recommended Posts

This simple dllcall gives me error 5, access denied,

Func _WinAPI_VkKeyScan($__key)
    _WinAPI_SetLastError(0)
    $res = DllCall('User32.dll', 'SHORT', 'VkKeyScan', 'CHAR', $__key)
    _xConsole('res: '&$res)
    $_LastErr = _WinAPI_GetLastError()
    If $_LastErr <> 0 Then _xConsole('Err: {' & $_LastErr & '}> ' & _WinAPI_GetLastErrorMessage())
    Return $res
EndFunc

Am i doing something wrong?

Also tried VkKeyScanA and W

Edit:

I want to send `:` via PostMessage() WM_KEYDOWN

Edited by xYuri
Missing Info

Share this post


Link to post
Share on other sites

@KaFu Thank you very much for your answer,

Sorry that i forgot to include this in my question,

But it still not doing what i really wanted, in first place i used `VkKeyScan` to get the shift+ code for `;` which makes it `:`, 

Now even after using ProgAndy's code it still send `;` , which i can get from https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes,

 

Also `GetLastError()` still gives error code 5, which is weird cuz it give a VKCode to a key.

Screenshot_1.png

Share this post


Link to post
Share on other sites

@Nine Yes i am aware of that, and i am sending to the right control as it show ;;;; in notepad i think?

Anyway here is the code,

Func _WinAPI_VkKeyScanW($__key)
    _WinAPI_SetLastError(0)
    $res = DllCall('User32.dll', 'SHORT', 'VkKeyScanW', 'USHORT', AscW($__key))
    _xConsole('res: ' & $res[0])
    $_LastErr = _WinAPI_GetLastError()
    If @error Then _xConsole('Err: {' & @error & '}> ' & _WinAPI_GetLastErrorMessage())
    Return SetExtended(BitShift($res[0], 8), BitAnd($res[0], 0xFF))
EndFunc   ;==>_WinAPI_VkKeyScan

$h = WinGetHandle('[CLASS:Notepad]')
MsgBox(0, '', $h)
$C_H = ControlGetHandle($h, '', '[CLASS:Edit; INSTANCE:1]')
_WinAPI_PostMessageW($C_H, $WM_KeyDown, _winapi_VkKeyScanW(':'), 2)

 

Result:

Screenshot_1.png

Edited by xYuri

Share this post


Link to post
Share on other sites

@Nine

Oh well, thanks very much, it worked as expected,

I feel really dumb as i tried sending WM_CHAR before, but without passing it thru Asc() :frantics:.

Again THANKS!

Share this post


Link to post
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

  • Similar Content

    • By Sori
      Not going to dump the code down because it's essentially a keylogger.
      <snip>
    • By Skysnake
      This is relevant
      From here https://stackoverflow.com/questions/3454315/is-it-possible-to-pin-a-dll-in-memory-to-prevent-unloading
      I use several UDFs on the Forum to do various things.  Those UDFs work very well.
      Effectively the UDFs are DLL wrappers, that make it possible to access DLL functions easily without the long hard slog of DLLCall() every time.
      However, I have now run into the issue that multiple UDF DLLCalls are slow. Not mind numbingly slow, but slow enough to become noticeable with a large of repeated function calls.
      So I was wondering, is it possible to "load a DLL into memory" and leave it there for the duration of my script's lifetime, avoid repeated DLL on-disk reads with a persistent in memory DLL?
      From Microsoft
      https://docs.microsoft.com/en-us/windows/desktop/dlls/about-dynamic-link-libraries
      Looks like what I want to do is: load-time dynamic linking,
      So next question, (a) how do I do this with AutoIt (b) How would this impact on standard AutoIt type DLL calls?
       
      The point is speed.  Is there a different approach?
      Or am I barking up the wrong tree?
      Skysnake
    • By supersonic
      Hi -
      Currently I'm playing around with Windows Credential Manager. I'm trying to access it with DllCall("advapi32.dll", ...) using the functions 'CredWriteW', 'CredReadW' and 'CredDeleteW'. All well. Another function I have to deal with is 'CredEnumerateW': https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credenumeratew/ .
      That's the test code I have so far:
      #include <Array.au3> #include <String.au3> Local $tCredentialsCount = DllStructCreate("DWORD;") Local $tPointerToArrayOfPointers = DllStructCreate("PTR;") ; Local $tPointerToArrayOfPointers = DllStructCreate(_StringRepeat("PTR;", 200)) ; ??? Local $aResult = DllCall("advapi32.dll", "BOOL", "CredEnumerateW", _ "WSTR", Null, "DWORD", 1, "DWORD", DllStructGetPtr($tCredentialsCount), "PTR", DllStructGetPtr($tPointerToArrayOfPointers)) If (Not @error) Then Local $iCredentialsCount = DllStructGetData($tCredentialsCount, 1) _ArrayDisplay($aResult, $iCredentialsCount) Local $hPointerToArrayOfPointers = DllStructGetData($tPointerToArrayOfPointers, 1) MsgBox(0, "$hPointerToArrayOfPointers", $hPointerToArrayOfPointers) ; Fails... For $i = 1 To 10 ; $iCredentialsCount MsgBox(0, $i & "___" & (($i * 2) - 1), DllStructGetData($tPointerToArrayOfPointers, ($i * 2) - 1)) Next $tCredentialsCount = 0 $tPointerToArrayOfPointers = 0 DllCall("advapi32.dll", "NONE", "CredFreeW", "PTR", $hPointerToArrayOfPointers) EndIf The DllCall seems to function properly - I get a valid count of credentials (on my computer ~ 133) and a pointer "to array of pointers".
      What is meant by "array of pointers"?
      Microsoft says: Pointer to an array of pointers to credentials. The returned credential is a single allocated block. Any pointers contained within the buffer are pointers to locations within this single allocated block.
      How to access these pointers... Contained within the buffer???
      Any information you can provide me would be greatly appreciated.
    • By bladem2003
      Hello,
      i need help to translate the c code to autoit .
      I don't understand the callback function.
       
      #include <windows.h> #include <stdio.h> // native IR Data by PAnsiChar typedef void CALLBACK CallBackPAnsiChar(char*, char*, char*, char*); typedef int (__stdcall *impInitPAnsiChar)(CallBackPAnsiChar); CALLBACK MyCallBackPAnsiChar(char* Protocol, char* Address, char* Command, char* Flags) { printf("\nIR Data received: Protocol: %s, Address: 0x%s, Command: 0x%s, Flags: 0x%s", Protocol, Address, Command, Flags); fflush(stdout); } int main(int argc, char **argv) { impInitPAnsiChar InitPAnsiChar = NULL; // Load DLL file HINSTANCE hinstLib = LoadLibrary(TEXT("USB_IR_Remote_Receiver.dll")); if (hinstLib == NULL) { printf("\nERROR: unable to load DLL\n"); return 1; } // Get function pointer InitPAnsiChar InitPAnsiChar = (impInitPAnsiChar)GetProcAddress(hinstLib, "InitPAnsiChar"); if (InitPAnsiChar == NULL) { printf("\nERROR: unable to find DLL function\n"); FreeLibrary(hinstLib); return 1; } if (InitPAnsiChar(*MyCallBackPAnsiChar)) { printf("\nInit DLL with InitPAnsiChar successfull"); } else { // Unload DLL file FreeLibrary(hinstLib); return 0; } while(1) { } //return 0; }  
    • By TheDcoder
      Hi, I thought I would never post a C/WinAPI related question in this forum ever, but here we are after a few years and me having learnt enough of C to write a basic console program
      My issue is that I am trying to read my child process's stdout output but ReadFile never returns if the child exits or if it is killed... very strange , I have been trying to work my way around this. The options I can think of are:
      Create a new thread and check for existance of the process constantly while reading Somehow make the pipe asynchronous (overlapped) so that I can read it in a non-blocking manner Fix ReadFile to return when the process ends Obviously I would prefer No. 3, I just want to make my program work. Here is my code if you guys want to take a look:
      // No text highlighting for C/C++ but we have it for C#? Blasphemy! bool allium_start(struct TorInstance *instance, char *config, allium_pipe *output_pipes) { char *cmd; // Figure out the command string for execution if (config) { char *parameters = " -f -"; cmd = malloc(strlen(instance->tor_path) + strlen(parameters) + 1); if (!cmd) return false; strcpy(cmd, instance->tor_path); strcat(cmd, parameters); } else cmd = instance->tor_path; // Prepare startup info with appropriate information SecureZeroMemory(&instance->startup_info, sizeof instance->startup_info); instance->startup_info.dwFlags = STARTF_USESTDHANDLES; SECURITY_ATTRIBUTES pipe_secu_attribs = {sizeof(SECURITY_ATTRIBUTES), NULL, true}; HANDLE pipes[2]; if (output_pipes == NULL) { CreatePipe(&pipes[0], &pipes[1], &pipe_secu_attribs, 0); output_pipes = pipes; } instance->startup_info.hStdOutput = output_pipes[1]; instance->startup_info.hStdError = output_pipes[1]; instance->stdout_pipe = output_pipes[0]; // Stored for internal reference if (config) { // Reuse the pipes array to store standard input pipes CreatePipe(&pipes[0], &pipes[1], &pipe_secu_attribs, 0); instance->startup_info.hStdInput = pipes[0]; } // Create the process bool success = CreateProcessA( NULL, cmd, NULL, NULL, config ? true : false, 0, NULL, NULL, &instance->startup_info, SecureZeroMemory(&instance->process, sizeof instance->process) ); // Free command string if needed if (config) free(cmd); // Write config to Tor's standard input unsigned long bytes_written; if (success) { WriteFile(pipes[1], config, strlen(config), &bytes_written, NULL); // Work around for simulating Ctrl + Z which sends the substitution character (ASCII 26), // this is needed in order for Tor to detect EOT/EOF while reading the config WriteFile(pipes[1], &(char){26}, 1, &bytes_written, NULL); } CloseHandle(pipes[1]); // Return on failure if (!success) return false; } char *allium_read_stdout_line(struct TorInstance *instance) { char *buffer = instance->buffer.data; // Check for valid buffer and allocate if needed if (instance->buffer.size == 0 || !buffer) { buffer = instance->buffer.data = malloc(instance->buffer.size = 80 + 1); if (!buffer) return NULL; } // Process the input unsigned int read_len = 0; while (true) { // Read data unsigned long bytes_read; if (ReadFile(instance->stdout_pipe, buffer, 1, &bytes_read, NULL) == false || bytes_read == 0) return NULL; // Check if we have reached end of line if (buffer[0] == '\n') break; // Proceed to the next character ++buffer; ++read_len; // Resize buffer if it is full if (read_len == instance->buffer.size) { char *new_buffer = malloc(instance->buffer.size += 50); if (new_buffer) memcpy(new_buffer, instance->buffer.data, read_len); free(instance->buffer.data); if (!new_buffer) return NULL; instance->buffer.data = new_buffer; buffer = instance->buffer.data + read_len; } } // Terminate the new line with null character and return // Special handling for Windows, terminate at CR if present buffer[read_len >= 2 && buffer[-1] == '\r' ? -1 : 0] = '\0'; } The allium_start function creates the redirection pipes and the child process, the other allium_read_stdout_line function reads from the stdout pipe created by the first function, ReadFile in this function does not return when the child ends or gets killed.

      I appriciate the help of the WinAPI gurus here, thanks in advance!
×
×
  • Create New...