What's wrong with the C code below? - c

The code below is from this answer:
#include <windows.h>
int main()
{
HANDLE h = ::CreateFile(L"\\\\.\\d:", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
STORAGE_DEVICE_NUMBER info = {};
DWORD bytesReturned = 0;
::DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &info, sizeof(info), &bytesReturned, NULL);
}
When I compile and run the above,get error like this:
error C2059: syntax error : ':'
error C2059: syntax error : '}'
error C2143: syntax error : missing ';' before ':'
UPDATE
AFter saving the above as a cpp file,I got this error:
error C2664: 'CreateFileA' : cannot convert parameter 1 from 'const wchar_t [7]' to 'LPCSTR'

Plain C doesn't have namespaces, so you need to leave out the :: global namespace specifiers. Those would only be valid in C++.
The L in front of the string specifies that this is a wide character string. If your project doesn't use wide characters, leave out the L to get a normal character string. If you need to support both variants you can also use the _T macro: _T("...") expands to the correct variant of string literal depending on your project settings.

I'm pretty sure that you can't use :: as part of an identifier name in the C programming language. This looks more like some bizarre, bastardized usage of C++. IIRC, :: by itself in front of an identifier specified that this was in the global or file scope (to avoid potentially clashing with, say, methods in a class).

It's not C, it's C++. Drop the double colons (or compile it as C++).
Also, the string constant uses wide characters. Drop the L in front of the open quote.

So, I guess your question is more about getting the result you want than the reason for the code not compiling :)
Now you've got it working, the DeviceIoControl() call will be filling in the STORAGE_DEVICE_NUMBER structure you're passing to it with the results you want. So, you should find that info.DeviceType now holds the device type, info.DeviceNumber holds the device number, and info.PartitionNumber the partition number.
Test for success before using the returned values. I'd maybe try it on the C: drive rather than the D: drive, as you're doing at the moment, until I was sure it was working; at least you know you've pretty much always got a C: drive in Windows :) So, use \\\\.\\c: rather than \\\\.\\d:.
Anyway, untested, but:
if (::DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &info, sizeof(info), &bytesReturned, NULL))
{
std::cout << "Device: " << info.DeviceNumber <<
" Partition: " << info.PartitionNumber << std::endl;
} else {
std::cerr << "Ooops. The DeviceIoControl call returned failure." << std::endl;
}
...obviously, you'd need a #include <iostream> for this to work, as I'm dumping the values using iostream, but you can print these out however you want, or message box them, bearing in mind you're already bringing in windows.h.
Bear in mind it's been a decade or so since I did any Windows C++ work, but maybe this'll get you going...

Related

Pointer decryption function not working as intended

First of all, it is important to say that the code will be a mess, I know that and there is a reason behind the messy code, but I prefer not to specify why to avoid going off track.
This snippet of code decrypts a pointer:
//LLUNGO is long long
//PLLUNGO is long long pointer
//SCANVELOCE is __fastcall
LLUNGO SCANVELOCE DecryptPointer(PPTR_SECRET _pSecret, PLLUNGO _OldPointer)
{
_OldPointer = (PLLUNGO) PTR_ENCRYPTION_ALGORITHM(*_OldPointer, _pSecret->Segreto);
INTERO Reference = GetReferenceToPtr(_pSecret, _OldPointer);
if (PTR_BAD_REFERENCE(Reference))
QUICK_PRINT("Bad reference error.\n");
return PTR_ENCRYPTION_ALGORITHM((LLUNGO)_pSecret->Riferimenti[Reference], _pSecret->Segreto);
}
using the following macros:
#define PTR_ENCRYPTION_ALGORITHM(PTR, KEY) (~(PTR ^ KEY))
#define PTR_BAD_REFERENCE(PTR) ((-1) == (PTR))
Now the problem is when I use the macro stated below, for some reason even if I am using the right arguments it is still throwing me this error:
no instance of overloaded function "DecryptPointer" corresponds to the
arguments.
Consider that NBYTE is BYTE and REGISTRA is the register keyword.
NBYTE SCANVELOCE MFINIT(LLUNGO _FuncAddr, PMUTILATE_FUNCTION _Function)
{
if (!_FuncAddr || !_Function)
return FALSO;
SELF_PTR_DECRYPTION( _FuncAddr ); //error thrown here
SELF_PTR_DECRYPTION( _Function ); //and here too!
for (REGISTRA PNBYTE Current = (PNBYTE)_FuncAddr; ; Current--)
{
if (MF_PUSH_EBP == *Current)
{
_Function->Inizio = (LLUNGO)Current;
break;
}
}
And the SELF_PTR_DECRYPTION macro + everything else necessary for the DecryptPointer function to work:
(PTR_SECRET being a struct)
#define SELF_PTR_DECRYPTION(X) ((X) = (PTR_DECRYPTION(X)))
#define PTR_DECRYPTION(X) DecryptPointer(&PTR_SECRET_NAME, X)
#define PTR_SECRET_NAME g_PTR_SECRET
INIT(PTR_SECRET PTR_SECRET_NAME);
Again sorry for the stupidly messy code, I'm struggling too, just like everyone reading this probably will, but again there is a reason behind the mess.
The solution has been found in the comments by #yano:
you've taken me straight to macro hell. If I'm following correctly,
_FuncAddr in the SELF_PTR_DECRYPTION( _FuncAddr ); call ends up being the 2nd argument to DecryptPointer, which expects a PLLUNGO type.
However, _FuncAddr is a LLUNGO type. And if its complaining about "no
overloaded function" it sounds like you're using a C++ compiler, not
C.
Many thanks, and sorry for the absolute mess of code I presented here.

Coq VST Internal structure copying

run into a problem with VST(Verified Software Toolchain) 2.5v library for Coq 8.10.1:
Got an error with the latest working commit of VST namely "Internal structure copying is not supported".
Minimal example:
struct foo {unsigned int a;};
struct foo f() {
struct foo q;
return q; }
On starting proof got an error:
Error: Tactic failure: The expression (_q)%expr contains internal structure-copying, a feature of C not currently supported in Verifiable C (level 97).
This is due to the check_normalized in floyd/forward.v :
Fixpoint check_norm_expr (e: expr) : diagnose_expr :=
match e with
| Evar _ ty => diagnose_this_expr (access_mode ty) e
...
So, the questions are:
1) What suggested workarounds exists?
2) What is the reason for this limitation?
3) Where can I get a list of unsupported features?
1) The workaround is to change your C program to copy field by field.
2) The reason is the absurdly complicated and target-ISA-dependent implementation/semantics of C's structure-copying, especially in parameter passing and function-return.
3) The first 10 lines of Chapter 4 ("Verifiable C and clightgen") of the reference manual has a short list of unsupported features, but unfortunately struct-by-copy is not on that list. That's a bug.

Calling dll from a Win32 Console Application [C]

Hi everyone and thank you for your time. This was created in Visual Studio 2012,and I'm using the standard Windows Libraries.
I am attempting to call a DLL function explicitly and I believe the code I've written is correct; however, I am receiving an error. I'm not sure if it's an error in something that I've written in the small C console application or from the DLL which I do not have access to the internal workings of.
//global area
HINSTANCE _createInstance;
typedef UINT (CALLBACK* LPFNDLLFUNCLOOKUP)(AccuInput*, AccuOut*);
LPFNDLLFUNCLOOKUP lpfnDllFuncCASSLookup;
typedef UINT (CALLBACK* LPFNDLLFUNCINIT)(BSTR);
LPFNDLLFUNCINIT lpfnDllFuncInit;
typedef UINT (CALLBACK* LPFNDLLFUNCCLOSE)();
LPFNDLLFUNCCLOSE lpfnDllFuncClose;
HMODULE unmanagedLib;
Here is my main function:
int main() {
// Load Library
BSTR configFile;
unmanagedLib = LoadLibraryA((LPCSTR) "AccuAddressUnMgd.dll");
// Initialize AccuAddress COM dll
lpfnDllFuncInit = (LPFNDLLFUNCINIT)GetProcAddress(unmanagedLib, (LPCSTR)"Init");
// This function will lookup the address
lpfnDllFuncCASSLookup = (LPFNDLLFUNCLOOKUP)GetProcAddress(unmanagedLib, (LPCSTR)"AccuCassLookup");
// This function will call AccuAddress COM DLL Close function
lpfnDllFuncClose = (LPFNDLLFUNCCLOSE)GetProcAddress(unmanagedLib, (LPCSTR)"Close");
// Append “config.acu” file path.
configFile = SysAllocString(L"C:\PathTo\Config.acu");
printf("ConfigPath created");
lpfnDllFuncInit(configFile);
printf("ConfigFile consumed");
SysFreeString(configFile);
return 0;
}
This is the error that I receive:
Unhandled exception at at 0x75D4C54F in RDISample1.exe: Microsoft C++ exception: _com_error at memory location 0x001AFAC0.
The error occurs at:
lpfnDllFuncInit(configFile);
So, I guess my question is two parts. Based off the code can I say for a fact that the error is in the DLL function?
Second question, when calling GetProcAddress what would be the point (if any) for encapsulating the string in LPCSTR like a function versus typecasting?
ie
lpfnDllFuncClose = (LPFNDLLFUNCCLOSE)GetProcAddress(unmanagedLib, LPCSTR("Close"));
Thanks again for the help. I've been doing a fair amount of research yet DLLs still have been puzzled.
The initial error is caused by the library you're using failing to correctly handle a file that doesn't exist.
The path you gave contains single slashes \, which are treated as escape characters, not path separators. Path separators must be escaped, i.e. \\ to be treated correctly.
There is no point casting a string literal to LPCSTR.
As for the _com_error that is definitely coming from the DLL. I would suggest wrapping that in a:
try
{
...
} catch(_com_error const & e)
{
wprintf(L"Caught a com error: %s\r\n", e.ErrorMessage());
}
And then you might be able to figure out what is wrong.

error: stray '\302' in program

I have the following piece of code (kernel code to be more specific) :
static int is_sram_locked(void)
{
if (OMAP2_DEVICE_TYPE_GP == omap_type()) {
/* RAMFW: R/W access to all initiators for all qualifier sets */
if (cpu_is_omap242x()) {
__raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
__raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */
__raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
}
if (cpu_is_omap34xx() && !cpu_is_am33xx()) {
__raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
__raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */
__raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
__raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2);
__raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0);
}
return 0;
} else
return 1; /* assume locked with no PPA or security driver */
}
This is copy-pasted from sublime 3, and as the title states, I get the following compilation error :
error: stray '\302' in program
error: stray '\273' in program
On lines that start with __raw_writel( ... )
I have done research about the problem and I found out that this error tells me that there is an unprintable character on the line in cause.
'\302 \273' is UTF-8 code for '»' (RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK)
I read that this problem often appears when you copy-paste code from somewhere else and those unprintable characters may have skipped your attention or your keyboard has a different layout that types strange characters. I inspected the code very closely and I could not find any of those foreign characters.
My big question is how can kernel code that I have never touched can present such errors ? And I have more than one file that comes with this error, which brings me to the fact that there might be something else wrong.
I have figured it out that I get this error on lines that start with anything else but a letter such as : '_' and '.' (these are the examples that rise issues for me so far)
Solutions I have tried :
Re-writing the entire lines;
Copy-paste the code into many UTF-8 unprintable character filters so I can find the 'stray' characters
Unicode Character Highlighter sublime packages
Note: I'm also using vim as editor and my .vimrc puts '»' as TABS and '·' as SPACES but only for indentation purposes, not as actual characters. I've fixed some similar errors when I copy-pasted from vim and those characters were actually in text, I deleted the characters and it got fixed. But for this I can't identify any 'stray' characters present in the code.
I'm out of ideas I can try to get over this so I'm asking for your help.
The macros were the problem. They referred to some macros I modified with some copy-paste code and completely forgot about it.
Special thanks to all.

Undeclared Identifier although it is declared

for a program in which I try to create a file and later write into it, I have written the following:
int main(){
...
....
(some code)
....
char DataBuffer[] = "This is the test file";
...
...
}
I get the error "DataBuffer: undeclared identifier" .
I am using Microsoft Visual C++ Express. And in an old asked question here in stackoverflow.com, I have read that Visual C++ uses an old C89 standard and that it does not support C99 standard.
For that reason, I must declare the variables at the beginning(which I did for the rest of the parameters of CreateFile() and WriteFile). I mean, when you consider the following:
DWORD dwCreationDisposition = CREATE_NEW;
Then I split it up and changed it to:
DWORD dwCreationDisposition;
...
dwCreationDisposition = CREATE_NEW
but I do not know how I should do it with an array. So, for example when I write:
char DataBuffer[];
....
DataBuffer[] = = "This is the test file";
Then I also get the same error message.
What can I do ? Is there any possibility to change the compiler options ? Or a chance to rewrite it such that the integrated compiler accepts it as the other splitted variables/parameters ?
best regards,
If you want your string to be re-writable you should so this:
char DataBuffer[MAX_SIZE];
....
strcpy(DataBuffer,"This is the test file");
Also consider using strncpy for avoiding buffer overrun error.
If your string is constant then:
const char DataBuffer[] = "This is the test file";

Resources