error C2440: '=' : cannot convert from 'void *' to 'NTSTATUS (__stdcall *)(HANDLE,ULONG,POBJECT_ATTRIBUTES)'
подскажите плиз в чем дело?
исходник:
#include "stdafx.h"
VOID LocateNTDLLEntryPoints()
{
if( !(NtOpenKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtOpenKey" )) ) {
printf("Could not find NtCreateKey entry point in NTDLL.DLL\n");
exit(1);
}
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
Здравствуйте, bvv2727, Вы писали:
B>error C2440: '=' : cannot convert from 'void *' to 'NTSTATUS (__stdcall *)(HANDLE,ULONG,POBJECT_ATTRIBUTES)'
B>подскажите плиз в чем дело?
B>исходник:
B>#include "stdafx.h"
B>VOID LocateNTDLLEntryPoints()
B>{
B> if( !(NtOpenKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
B> "NtOpenKey" )) ) {
B> printf("Could not find NtCreateKey entry point in NTDLL.DLL\n");
B> exit(1);
B> }
B>}
B>BOOL APIENTRY DllMain( HANDLE hModule,
B> DWORD ul_reason_for_call,
B> LPVOID lpReserved
B> )
B>{
B> return TRUE;
B>}
тебе ж написали. Какой тип у NtOpenKey? 'NTSTATUS (__stdcall *)(HANDLE,ULONG,POBJECT_ATTRIBUTES)'? Тогда к нему и приводи результата GetProcAddress
От:
Кодт
Дата: 19.07.06 13:27
Оценка:
Здравствуйте, bvv2727, Вы писали:
B>error C2440: '=' : cannot convert from 'void *' to 'NTSTATUS (__stdcall *)(HANDLE,ULONG,POBJECT_ATTRIBUTES)'
B>подскажите плиз в чем дело?
B> if ( !(NtOpenKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll" ),
B> "NtOpenKey" )) ) {
Очевидно, дело в том, что NtOpenKey объявлен как
NTSTATUS __stdcall NtOpenKey(HANDLE,ULONG,POBJECT_ATTRIBUTES);
А ты пытаешься присвоить ему (void*)blablabla.
Правильно так:
typedef NTSTATUS (__stdcall *PFN_NtOpenKey)(HANDLE,ULONG,POBJECT_ATTRIBUTES); // объявили тип функции - чтобы не повторяться
PFN_NtOpenKey pfnNtOpenKey; // указатель на функцию; не будем устраивать путаницу с SDK-шными именами, дадим уникальное
if ( !(pfnNtOpenKey = (PFN_NtOpenKey) GetProcAddress( GetModuleHandle("ntdll.dll" ), "NtOpenKey" )) )
{ .... }
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[2]: создаю DLL - ошибка
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, bvv2727, Вы писали:
B>>error C2440: '=' : cannot convert from 'void *' to 'NTSTATUS (__stdcall *)(HANDLE,ULONG,POBJECT_ATTRIBUTES)'
B>>подскажите плиз в чем дело?
B>>исходник:
B>>#include "stdafx.h"
B>>VOID LocateNTDLLEntryPoints()
B>>{
B>> if( !(NtOpenKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
B>> "NtOpenKey" )) ) {
B>> printf("Could not find NtCreateKey entry point in NTDLL.DLL\n");
B>> exit(1);
B>> }
B>>}
B>>BOOL APIENTRY DllMain( HANDLE hModule,
B>> DWORD ul_reason_for_call,
B>> LPVOID lpReserved
B>> )
B>>{
B>> return TRUE;
B>>}
КЛ>тебе ж написали. Какой тип у NtOpenKey? 'NTSTATUS (__stdcall *)(HANDLE,ULONG,POBJECT_ATTRIBUTES)'? Тогда к нему и приводи результата GetProcAddress
подскажи плиз как написать,
я на си++ не писал...
NTSTATUS (__stdcall *NtOpenKey)(
HANDLE KeyHandle,
ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes
);
Re[2]: создаю DLL - ошибка
СПАСИБО
Re[2]: создаю DLL - ошибка
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, bvv2727, Вы писали:
B>>error C2440: '=' : cannot convert from 'void *' to 'NTSTATUS (__stdcall *)(HANDLE,ULONG,POBJECT_ATTRIBUTES)'
B>>подскажите плиз в чем дело?
К>B>> if ( !(NtOpenKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll" ),
B>> "NtOpenKey" )) ) {
К>
К>Очевидно, дело в том, что NtOpenKey объявлен как
К>К>NTSTATUS __stdcall NtOpenKey(HANDLE,ULONG,POBJECT_ATTRIBUTES);
К>
К>А ты пытаешься присвоить ему (void*)blablabla.
К>Правильно так:
К>К>typedef NTSTATUS (__stdcall *PFN_NtOpenKey)(HANDLE,ULONG,POBJECT_ATTRIBUTES); // объявили тип функции - чтобы не повторяться
К>PFN_NtOpenKey pfnNtOpenKey; // указатель на функцию; не будем устраивать путаницу с SDK-шными именами, дадим уникальное
К>if ( !(pfnNtOpenKey = (PFN_NtOpenKey) GetProcAddress( GetModuleHandle("ntdll.dll" ), "NtOpenKey" )) )
К>{ .... }
К>
выдало ошибку
error LNK2005: "long (__stdcall* NtOpenKey)(void *,unsigned long,struct _OBJECT_ATTRIBUTES *)" (?NtOpenKey@@3P6GJPAXKPAU_OBJECT_ATTRIBUTES@@@ZA) already defined in dll3.obj
при
Status = NtOpenKey( &SoftwareKeyHandle, KEY_ALL_ACCESS,
&ObjectAttributes );
Re[3]: создаю DLL - ошибка
От:
Кодт
Дата: 19.07.06 14:18
Оценка:
Здравствуйте, bvv2727, Вы писали:
B>выдало ошибку
B>error LNK2005: "long (__stdcall* NtOpenKey)(void *,unsigned long,struct _OBJECT_ATTRIBUTES *)" (?NtOpenKey@@3P6GJPAXKPAU_OBJECT_ATTRIBUTES@@@ZA) already defined in dll3.obj
Значит, эта переменная уже определена — в той самой dll3, и незачем её определять ещё раз.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[4]: создаю DLL - ошибка
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, bvv2727, Вы писали:
B>>выдало ошибку
B>>error LNK2005: "long (__stdcall* NtOpenKey)(void *,unsigned long,struct _OBJECT_ATTRIBUTES *)" (?NtOpenKey@@3P6GJPAXKPAU_OBJECT_ATTRIBUTES@@@ZA) already defined in dll3.obj
К>Значит, эта переменная уже определена — в той самой dll3, и незачем её определять ещё раз.
ошибка после строки:
Status = NtOpenKey( &SoftwareKeyHandle, KEY_ALL_ACCESS,
&ObjectAttributes );
не пойму — почему
я же ничего не объявляю
на всяк случай содержимое хедера:
#define OBJ_CASE_INSENSITIVE 0x40
typedef DWORD ULONG;
typedef WORD USHORT;
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
NTSTATUS (__stdcall *NtCreateKey)(
HANDLE KeyHandle,
ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions,
PULONG Disposition
);
NTSTATUS (__stdcall *NtOpenKey)(
HANDLE KeyHandle,
ULONG DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes
);
NTSTATUS (__stdcall *NtSetValueKey)(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex, /* optional */
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
NTSTATUS (__stdcall *NtDeleteKey)(
HANDLE KeyHandle
);
Re[5]: создаю DLL - ошибка
код:
#include "stdafx.h"
WCHAR KeyNameBuffer[] = L"\\Registry\\Machine\\Software";
WCHAR Buffer1[] = L"_A";//L"Classes";
WCHAR Buffer2[] = L"_B";//L"Classes";
WCHAR BufferEnd[] = L"_C";
WCHAR HiddenValueNameBuffer[]= L"Hidden Value";
UNICODE_STRING KeyName, ValueName;
HANDLE SoftwareKeyHandle, SysKeyHandle, HiddenKeyHandle, Buffer1Handle, Buffer2Handle, Buffer3Handle, Buffer4Handle;
ULONG Status;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG Disposition;
char input;
//
// Convenience output routine
//
VOID Output( char *msg, DWORD Buttons )
{
MessageBox( NULL, msg, "RegHide", Buttons );
}
extern "C" __declspec(dllexport) int LocateNTDLLEntryPoints()
{
typedef NTSTATUS (__stdcall *PFN_NtOpenKey)(HANDLE,ULONG,POBJECT_ATTRIBUTES); // объявили тип функции — чтобы не повторяться
PFN_NtOpenKey pfnNtOpenKey; // указатель на функцию; не будем устраивать путаницу с SDK-шными именами, дадим уникальное
if( !(pfnNtOpenKey = (PFN_NtOpenKey) GetProcAddress( GetModuleHandle("ntdll.dll"), "NtOpenKey" )) )
//if( !(NtOpenKey = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),"NtOpenKey" )) )
{
printf("Could not find NtCreateKey entry point in NTDLL.DLL\n");
return -1;
}
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" __declspec(dllexport) int A()
{
LocateNTDLLEntryPoints();
KeyName.Buffer = KeyNameBuffer;
KeyName.Length = (short)wcslen( KeyNameBuffer ) *sizeof(WCHAR);
InitializeObjectAttributes( &ObjectAttributes, &KeyName,
OBJ_CASE_INSENSITIVE, NULL, NULL );
Status = NtOpenKey( &SoftwareKeyHandle, KEY_ALL_ACCESS,
&ObjectAttributes );
return 0;
}
Re[3]: создаю DLL - ошибка
Здравствуйте, bvv2727, Вы писали:
B>выдало ошибку
B>error LNK2005: "long (__stdcall* NtOpenKey)(void *,unsigned long,struct _OBJECT_ATTRIBUTES *)" (?NtOpenKey@@3P6GJPAXKPAU_OBJECT_ATTRIBUTES@@@ZA) already defined in dll3.obj
B>при
B>Status = NtOpenKey( &SoftwareKeyHandle, KEY_ALL_ACCESS,
B> &ObjectAttributes );
посмотри как делается по аналогии с этим:
char * Foo(int i); //допустим имеем в dll такую экспортируемую функцию
const char * (*pfnFoo)(int);
(FARPROC &)pfnFoo = GetProcAddress(..., "Foo");
char * sz = pfnFoo(2);
С Уважением.
Re[5]: создаю DLL - ошибка
От:
Кодт
Дата: 19.07.06 14:48
Оценка:
Здравствуйте, bvv2727, Вы писали:
К>>Значит, эта переменная уже определена — в той самой dll3, и незачем её определять ещё раз.
B>ошибка после строки:
B>Status = NtOpenKey( &SoftwareKeyHandle, KEY_ALL_ACCESS,
B> &ObjectAttributes );
Это та строка, которая спровоцировала линкер на использование переменной NtOpenKey.
B>не пойму — почему
B>я же ничего не объявляю
B>на всяк случай содержимое хедера:
Очень даже объявляешь. И более того, определяешь!
B>NTSTATUS (__stdcall *NtCreateKey)(
B> HANDLE KeyHandle,
B> ULONG DesiredAccess,
B> POBJECT_ATTRIBUTES ObjectAttributes,
B> ULONG TitleIndex,
B> PUNICODE_STRING Class,
B> ULONG CreateOptions,
B> PULONG Disposition
B> );
B>NTSTATUS (__stdcall *NtOpenKey)(
B> HANDLE KeyHandle,
B> ULONG DesiredAccess,
B> POBJECT_ATTRIBUTES ObjectAttributes
B> );
B>NTSTATUS (__stdcall *NtSetValueKey)(
B> IN HANDLE KeyHandle,
B> IN PUNICODE_STRING ValueName,
B> IN ULONG TitleIndex, /* optional */
B> IN ULONG Type,
B> IN PVOID Data,
B> IN ULONG DataSize
B> );
B>NTSTATUS (__stdcall *NtDeleteKey)(
B> HANDLE KeyHandle
B> );
Это три переменных типа "указатель на функцию".
P.S.
Разница между объявлением и определением состоит в том, что объявление утверждает: "неизвестно где есть такая переменная такого типа; линкер, найди её сам"; а определение — "так вот же она! компилятор, добавь её в .obj-файл и проинициализируй".
extern int x; // объявление
int x; // определение
// либо
int x = 12; // определение и явная инициализация
////////////////////////////////////////////////
class Foo
{
static int x; // объявление
};
int Foo::x; // определение
И если объявлений одного и того же в программе может быть много (естественно, они должны совпадать), то определение — ровно одно на всю программу, состоящую из компилирующихся .cpp- и .c-файлов и сторонних .lib- и .obj-файлов.
В данном случае линкер возмутился, что переменная NtOpenKey определена в your_file.cpp -> your_file.obj и ещё где-то в другом месте.
P.P.S.
Оборачивай сишный код тэгами [ccode] — [/ccode] (или [c] — [/c])
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[6]: создаю DLL - ошибка
СПАСИБО
все ОК
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить