создаю DLL - ошибка
От: bvv2727 Украина http://bvv.kiev.ua
Дата: 19.07.06 13:05
Оценка:
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;
}
Re: создаю DLL - ошибка
От: Константин Л. Франция  
Дата: 19.07.06 13:24
Оценка:
Здравствуйте, 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
Re: создаю DLL - ошибка
От: Кодт Россия  
Дата: 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 Украина http://bvv.kiev.ua
Дата: 19.07.06 13:30
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Здравствуйте, 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 - ошибка
От: bvv2727 Украина http://bvv.kiev.ua
Дата: 19.07.06 13:34
Оценка:
СПАСИБО
Re[2]: создаю DLL - ошибка
От: bvv2727 Украина http://bvv.kiev.ua
Дата: 19.07.06 14:06
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 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 Украина http://bvv.kiev.ua
Дата: 19.07.06 14:24
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 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 - ошибка
От: bvv2727 Украина http://bvv.kiev.ua
Дата: 19.07.06 14:30
Оценка:
код:
#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 - ошибка
От: Viktor Sklyar Украина  
Дата: 19.07.06 14:34
Оценка:
Здравствуйте, 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 - ошибка
От: bvv2727 Украина http://bvv.kiev.ua
Дата: 19.07.06 15:03
Оценка:
СПАСИБО
все ОК
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.