win32 API calls from cython - winapi

Hi i'm trying to call the CreateFileA win32 function from a pyx file (cython file)(windows.h is already included from the pxd file), but it doesn't work ... does anyone ever tried to do so... needs help please
More informations:
i got no errors when compiling with Mingw, but at the execution i get -1 as return value..
illustration :
myfile.pxd
cdef extern from "ftd2xx.h":
stuff....
# CreateFileA declaration
HANDLE **CreateFileA***(LPCSTR lpFileName, DWORD dwDesiredAccess,
DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)*
myfile.pyx
cimport myfile.pxd
def somefuction()
HANDLE a = myfile.**CreateFileA**(......)
at the execution i get -1

Negative 1 (-1 return) means there were multiple errors. It's possible that you are including from the wrong place.
Anyway, my python experience tells me that you can use win32all, from Mark Hammond, to call the win32api. That should solve all your problems.
If it doesn't:
I snooped around Stack Overflow and found lots of people had similar problems. Here are some things you can try:
mingw_setup_args={'options': {'build_ext': {'compiler': 'mingw32'}}}
import pyximport; pyximport.install(setup_args=mingw_setup_args)
Browse to: c:\Python2x\Lib\distutils\distutils.cfg:
[build]
compiler = mingw32
[build_ext]
compiler = mingw32
I encourage you to branch out. If you notice the right sidebar, "related" div on this page, you'll see that there are many people who have asked similar questions. I hope it gets you started. Alternatively, I recommend you look for a better compiler--something that will give you a full error report. Post the error report here. Try to be as precise as possible if there's anything you want to exclude, so that you remove as little helpful data as possible. You can definitely find a solution if one exists, provided you find a complete error message.
I'm almost certain that a full error report exists somewhere, and you just don't know where to look. I found out very early in my programming career that this is always the case when it seems there's "no error" to a programmer: they're looking in the wrong place. So, you should figure out where to look for a complete error report.

Related

Anyone know the location of SetProcessDpiAwarenessContext() in windows?

I need to turn off DPI scaling in my Win32 application. The recommended way to do this programmatically is via the call:
SetProcessDpiAwarenessContext()
I am using the mingw windows environment. I verified that mingw headers don't have the call, but then several newer calls are missing from the mingw headers. Its a lot of work to update those, I am sure.
I created a local definition of that:
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 3
extern BOOL SetProcessDpiAwarenessContext(int value);
int main()
{
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}
I still get:
C:\projects\petit_ami>gcc -g3 -Iinclude -Ilibc -static tests/widget_test.c -Wl,--whole-archive bin/petit_ami_graph.a -Wl,--no-whole-archive -lwinmm -lgdi32 -lcomdlg32 -lwsock32 -luser32 -o bin/widget_test
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: bin/petit_ami_graph.a(graphics.o): in function `pa_init_graph':
C:\projects\petit_ami/windows/graphics.c:15662: undefined reference to `SetProcessDpiAwarenessContext'
collect2.exe: error: ld returned 1 exit status
The best documentation I can find says it is in user32.dll.
This is using Windows 10 and recently updated, build: 19042.1052
Thanks for any help.
Scott Franco
San Jose, CA
Almost there. I did:
typedef BOOL (WINAPI *PGNSI)(int);
pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
"SetProcessDpiAwarenessContext");
if(NULL != pGNSI) {
dbg_printf(dlinfo, "Procedure found\n");
r = pGNSI(2);
dbg_printf(dlinfo, "r: %d\n", r);
if (!r) winerr();
}
And got:
C:\projects\petit_ami>graphics_test
windows/graphics.c:pa_init_graph():15686: Procedure found
windows/graphics.c:pa_init_graph():15688: r: 0
Error: Graph: Windows error: The parameter is incorrect.
The description of the parameter is here:
https://learn.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context
I saw elsewhere that 2 was a valid value, but clearly that may not be correct. The suggestion by Simon to get the Visual studio environment may be operative just to get the proper value. Apologies to Simon, I can't at the moment take the rest of your suggestion. There is a long list of reasons I don't want to bore people with here.
Continued:
I installed and ran the visual studio with sample code. It works, now I am trying to figure out what DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 is, it is not a simple integer.
Anyways, its late. I try to find the final answer tomorrow.
Continued:
The working code is:
/* function call for direct to dll */
typedef BOOL (WINAPI *PGNSI)(int);
/* select for highest DPI */
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 0xfffffffc
...
/* turn off scaling. The following call gets around the lack of a
declaration in mingw */
pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("user32.dll")),
"SetProcessDpiAwarenessContext");
if (NULL != pGNSI) {
r = pGNSI(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
if (!r) winerr();
}
As you could probably guess, I am going to tie this to a user option. Now I just need to research what the effect of this new mode is on widgets and other OS features.
Thanks for all the help.
GetProcAddress works and is the recommended method when you cannot be certain if the user's OS will have the function.
If you want to resolve the symbol at link time, you need to ensure that (1) the import library has the symbol, and (2) that the calling convention and name decoration and mangling are correct.
I'm not very familiar with mingw, but I believe it comes with import libraries for some version of common Windows DLLs. Since this is a newer function, it might not be in the import library. There are tools to scan an existing DLL and create a corresponding import library, so perhaps you need to build a fresh one.
The calling convention for Win32 is __stdcall. If your compiler is using a different calling convention by default, you'll have to set it explicitly on your forward declaration of the function. Also, if you're compiling in C++ mode, you'll need to wrap the forward declaration in an extern "C" to prevent name mangling. If either of these are wrong, you'll get an "undefined reference" diagnostic from the linker because the symbol will be "decorated" differently.

what does __init_refok keyword means in linux kernel code?

While browsing the kernel code, I came accross a keyword that is used in several kernel init functions, __init_refok.
some of the lines I came accross are like
void __init_refok free_initmem(void)
static void __init_refok vgacon_scrollback_startup(void)
const struct linux_logo * __init_refok fb_find_logo(int depth)
void noinline __init_refok rest_init(void)
and others.
I searched for the reference , from that I came to know that it is defined as a preprocessor macro in include/linux/init.h, line 71.
After browsing that, I got the following codes
#define __init_refok __ref
and
#define __ref __section(.ref.text) noinline
After that, I am losing track.
If anyone can let me know what is the purpose of using that keyword in the code, it will be very helpful.
[I am looking for the basic functionality achieved by using this keyword, just like using __init helps to put the initialization code in seperate memory location to be cleared after init process has been completed.]
Thanks in advance.
EDIT
In the include/linux/init.h, it is mentioned like __init_refok is to supress the warning from modpost check, due to any reference form normal code to init section code, but still, I am not getting it exactly. Does that mean that these codes will ba place somewhere else? How actually the behaviour differs from the normal behaviour by using __init_refok keyword?
To my understanding, include/linux/init.h clearly documents the purpose of __init_refok. As you have mentioned
using __init helps to put the initialization code in separate memory
location to be cleared after init process has been completed.
compiler generates a warning when we use the data or code from the separate memory as they might will be removed at the time of the execution of the particular code referencing them.
__init_refok is a way to tell the compiler that you are aware and consciously referencing the initialization code or data. It means ref erencing init section is ok for you. Thus compiler does not generate any warning.
The file also documents that, though the warning is suppressed, it is the programmer's responsibility write such code that refers init section data or code.
of course, no warning does not mean code is correct, so optimally
document why the __ref is needed and why it's OK
In your example, the functions free_initmem(void) is probably referring to some data or code, that are tagged with _init.
The _init_refok tag does not remove the code neither relocate. The code is treated as ordinary except, if it contains any reference to init code or data, warning will be suppressed.

How to read a call stack?

We have a native C++ application running via COM+ on a windows 2003 server. I've recently noticed from the event viewer that its throwing exceptions, specifically the C0000005 exception, which, according to http://blogs.msdn.com/calvin_hsia/archive/2004/06/30/170344.aspx means that the process is trying to write to memory not within its address space, aka access violation.
The entry in event viewer provides a call stack:
LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const *,class utilCDate &) + 0xa26c
LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const *,class utilCDate &) + 0x8af4
LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const *,class utilCDate &) + 0x13a1
LibFmwk!utilCLogController::GetFLFInfoLevel(void)const + 0x1070
LibFmwk!utilCLogController::GetFLFInfoLevel(void)const + 0x186
Now, I understand that its giving me method names to go look at but I get a feeling that the address at the end of each line (e.g. + 0xa26c) is trying to point me to a specific line or instruction within that method.
So my questions are:
Does anyone know how I might use this address or any other information in a call stack to determine which line within the code its falling over on?
Are there any resources out there that I could read to better understand call stacks,
Are there any freeware/opensource tools that could help in analysing a call stack, perhaps by attaching to a debug symbol file and/or binaries?
Edit:
As requested, here is the method that appears to be causing the problem:
BOOL UTIL_GetDateFromLogByDayDirectory(LPCSTR pszDir, utilCDate& oDate)
{
BOOL bRet = FALSE;
if ((pszDir[0] == '%') &&
::isdigit(pszDir[1]) && ::isdigit(pszDir[2]) &&
::isdigit(pszDir[3]) && ::isdigit(pszDir[4]) &&
::isdigit(pszDir[5]) && ::isdigit(pszDir[6]) &&
::isdigit(pszDir[7]) && ::isdigit(pszDir[8]) &&
!pszDir[9])
{
char acCopy[9];
::memcpy(acCopy, pszDir + 1, 8);
acCopy[8] = '\0';
int iDay = ::atoi(&acCopy[6]);
acCopy[6] = '\0';
int iMonth = ::atoi(&acCopy[4]);
acCopy[4] = '\0';
int iYear = ::atoi(&acCopy[0]);
oDate.Set(iDay, iMonth, iYear);
bRet = TRUE;
}
return (bRet);
}
This is code written over 10 years ago by a member of our company who has long since gone, so I don't presume to know exactly what this is doing but I do know its involved in the process of renaming a log directory from 'Today' to the specific date, e.g. %20090329. The array indexing, memcpy and address of operators do make it look rather suspicious.
Another problem we seem to have is that this only happens on the production system, we've never been able to reproduce it on our test systems or development systems here, which would allow us to attach a debugger.
Much appreciated!
Andy
Others have said this in-between the lines, but not explicitly. look at:
LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const *,class utilCDate &) + 0xa26c
The 0xa26c offset is huge, way past the end of the function. the debugger obviously doesn't have the proper symbols for LibFmwk so instead it's relying on the DLL exports and showing the offset relative to the closest one it can find.
So, yeah, get proper symbols and then it should be a breeze. UTIL_GetDateFromLogByDayDirectory is not at fault here.
if you really need to map those addresses to your functions - you'll need to work with .MAP file and see where those addresses really point to.
But being in your situation I would rather investigate this problem under debugger (e.g. MSVS debugger or windbg); as alternative (if crash happens at customer's site) you can generate crash dump and study it locally - it can be done via Windows MiniDumpWriteDump API or SysInternals ProcDump utility (http://download.sysinternals.com/Files/procdump.zip).
Make sure that all required symbol files are generated and available (also setup microsoft symbol server path so that windows DLLs' entry points get resolved also).
IMHO this is just the web site you need: http://www.dumpanalysis.org - which is the best resource to cover all your questions.
Consider also taking a look at this PDF - http://windbg.info/download/doc/pdf/WinDbg_A_to_Z_color.pdf
Point 2 and 3 are easily answered:
3rd Point. Any debugger. That's what they are made for. Set your debugger to break on this special exception. You should be able to click yourself through the callstack and find the different calls on the stack (at least delphi can do this, so visual studio should be able as well). Compile without optimisations if possible. OllyDBG might work as well - perhaps in combination with its trace functionality.
2nd Point. Any information about x86 Assembler, Reverseengineering ... Try: OpenRCE, NASM Documentation, ASM Community.
1st Point. The callstack tells you the functions. I don't know if it is written in order or in opposite order - so it might be that the first line is the last called function or the first called function. Follow the calls with the help of the debugger. Sometimes you can change between asm and code (depending on the debugger, map files ...). If you don't have the source - learn assembler, read about reverse engineering. Read the documentation of the functions you call in third party components. Perhaps you do not satisfy a precondition.
If you can tell a bit more about the programm (which parts of the source code do you have, is a library call involved?, ...)
Now some code-reading:
The function accepts a pointer to a zero terminated string and a reference to a date object. The pointer is assumed to be valid!
The function checks wether the string is in a specific format (% followed by 8 digits followed by a \0). If this is not the case, it returns false. This check (the big if) accesses the pointer without any validity checks. The length is not checked and if the pointer is pointing somewhere in the wild, this space is accessed. I don't know if a shorter string will cause problems. It shouldn't because of the way && is evaluated.
Then some memory is allocated on the stack. The number-part of the string is copied into it (which is ok) and the buffer gets its \0 termination. The atois extract the numbers. This will work because of the different start-locations used and the \0-termination after each part. Somehow tricky but nice. Some comments would have made everything clear.
These numbers are then inserted into the object. It should be valid since it is passed into the function by reference. I don't know if you can pass a reference to a deleted object but if this is the case, this might be your problem as well.
Anyway - except the missing check for the string-pointer, this function is sound and not the cause of your problem. It's only the place that throws the exception. Search for arguments that are passed into this function. Are they always valid? Do some logging.
I hope I didn't do any major mistakes as I am a Delphi programmer. If I did - feel free to comment.

Visual studio 2005: is there a compiler option to initialize all stack-based variables to zero?

This question HAS had to be asked before, so it kills me to ask it again, but I can't find it for all of my google and searching stackoverflow.
I'm porting a bunch of linux code to windows, and a good chunk of it makes the assumption that everything is automatically initialized to zero or null.
int whatever;
char* something;
...and then immediately doing something that may leave 'something' null, and testing against 'something'
if(something == NULL)
{
.......
}
I would REALLY like not to have to go back throughout this code and say:
int whatever = 0;
char* something = NULL;
Even though that is the proper way to deal with it. It's just very time consuming.
Otherwise, I declare a variable, and it's initialized to something crazy if I don't set it myself.
This option doesn't exist in MSVC, and honestly, whoever coded your application made a big mistake. That code is not portable, as C/C++ say that uninitialized variables have an undefined value. I suggest setting the "treat warnings as errors" option and recompiling; MSVC should give you a warning every time a variable is used without being initialized.
No - there's no option to do that in MSVC.
Debug builds will initialize them with something else (0xcc I think), but not zero. Unfortunately, your code is bugged and needs fixed (of course this applies only to automatic variables -for statics and globals it's fine to assume they're zero initialized). I'm surprised there was any compiler that supported that behavior - if there's an option to do that in GCC, I haven't heard of it (but I'm no expert in the dusty corners of GCC).
You may hear that an earlier version of MSVC would init variables to zero in debug builds (similar to the way 0xcc is used in VS 2005), but as far as I know that's untrue.
edit ----------
Well, I'll be damned - GCC does (or did?) have the -finit-local-zero option. Looks like it's there mostly for Fortran support, I think.
I'd suggest using compiler warnings about using uninitialized variables to help you catch 99% of your problems. I know it's not a great bit of work, but it should be done if at all possible.
Interestingly, MSVC now does have the ability to do this. The Microsoft Security team wrote a blog post about it here, and there's a CppCon talk here.
Unfortunately, it doesn't seem like this option is exposed to the public. This page lists a bunch of 'hidden MSVC flags', and it includes an option called -initall, so that might be it.
What I ended-up doing was switching to /w4. At this level, it caught most of the "yeah, that's going to be an issue" areas of initialization. Otherwise, there's nothing that can change everything from being 0xcccccccc on initialization to 0x00000000 that I saw.
Massive thanks to everyone for answering this, and yes, we will tighten it up in the future.

stange -I effect with make and bad -L

I am trying to build an automated build system. It took me a little while to change a working wii generic makefile to a working win32 (using mingw32) makefile.
my make is here http://pastie.org/319482
The weird effect is, if i remove the a preceding the paths in ABS_INCL (line 31) the build doesnt work and complains about missing a header which is specified by the first path. Why is it doing this? i cant track the problem down.
The next issue is when i dropped in code that requires libcurl, i can still compile but no longer link as expected. I added curl to my libs (line 47) and the path (line 53) and it looks like i am including it right and the lib is in the right order (i tried to touch as little as possible while converting wii to win32) and i cant see the problem. Does anyone know why this is happening?
here is simple source to test with
#include <stdio.h>
void main2();
int main( int argc, const char* argv[])
{
int a=0;
printf("hey");
main2();
return 0;
}
#include <curl/curl.h>
void main2()
{
CURL *curl = curl_easy_init();
curl_easy_cleanup(curl);
}
You're not getting a lot of answers here - I'm going to go out on a limb and tell you it's because of your really badly written title. I've read it maybe 20 times as it scrolled down the home page and I still don't really get it. There is the obvious spelling mistake, and I want to go in and fix that but then there is the whole weirdness with the "-l" and "-L" and I can't tell where you are going with that.
So, most people will look at that and just blank out and move on. Assuming they get past that, you failed to add the useful information contained within your makefile to the question and so you've gotta go off and read it on the other site.
Finally, as one more hurdle, your makefile is too long to easily read and absorb. So assuming someone like me who is really kind of determined goes and reads it, it's too difficult to tell where the problem could lie within that. You need to edit it down to probably ten lines or less, and then assuming you haven't been able to figure out the problem, you could then post just those few lines that showed the problem in your question and then with a decent title and some good descriptive text, you'll probably get your answer.
I'm guessing the answer to your question isn't even that hard, you've successfully managed to obfuscate it to the point that most people wont even bother.

Resources