how to convert a msvc exe project to a dll project? - visual-c++

in the exe project:
int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
g_hMainWnd=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)DialogProc);
RECT rcWnd;
GetWindowRect(g_hMainWnd,&rcWnd);
int X=(GetSystemMetrics(SM_CXSCREEN)-rcWnd.right+rcWnd.left)>>1,
Y=(GetSystemMetrics(SM_CYSCREEN)-rcWnd.bottom+rcWnd.top)>>1;
MoveWindow(g_hMainWnd,X,Y,rcWnd.right-rcWnd.left,rcWnd.bottom-rcWnd.top,FALSE);
ShowWindow(g_hMainWnd,SW_SHOW);
BOOL bRet;
MSG msg;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
MessageBox(NULL,_T("GetMessage error with -1 returned!"),_T("error"),MB_ICONHAND);
break;
}
else if (!IsWindow(g_hMainWnd) || !IsDialogMessage(g_hMainWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
I changed the project setting to output a dll firstly.
Then I changed the WinMain to:
BOOL APIENTRY DllMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
g_hMainWnd=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)DialogProc);
HWND hMainWnd;
//DialogProc involves the critical initialization of the data required for the export function used later
return 0;
}
So, if it is a foolish idea, or have I missed something?
Thank you all!

BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
For more informations: Dll entry point

The definition of DllMain is to be used by the operating system, and on a few occasions you must enter their codes. To execute the code that implements your EXE, you must create a public routine that receives the required parameters.
Use Visual Studio do create one library project to export some data and functions.
New Project-> Select Viasual c++ -> Select Win32 -> Win32 Project -> Name your project -> Next -> Select DLL -> Select Export symbols -> finish
The final project will contain a variable being exported and a public routine. Use as a template in your code.

Related

What happen with MFC CString in " CStringA csA = CStringW("hello", 5);"

It does compiled. But I do not think it should. It compile both in VS2008 and VS2013.
I Add a picture to show it does compile. but I am really confused at this. The picture is VS2013.
Why shouldn't it compile? There's explicit code in CString to handle exactly such unicode-to-ascii conversions:
CStringT& operator=(_In_opt_z_ PCYSTR pszSrc)
{
...
PXSTR pszBuffer = GetBuffer( nDestLength );
StringTraits::ConvertToBaseType( pszBuffer, nDestLength, pszSrc);
...
}
and internally (note the explicit LPSTR and LPCWSTR in the signature):
static void __cdecl ConvertToBaseType(
_Out_writes_(nDestLength) LPSTR pszDest,
_In_ int nDestLength,
_In_ LPCWSTR pszSrc,
_In_ int nSrcLength = -1) throw()
{
// nLen is in XCHARs
::WideCharToMultiByte( _AtlGetConversionACP(), 0, pszSrc, nSrcLength, pszDest, nDestLength, NULL, NULL );
}
You can step into it from the debugger.

I am having trouble getting my d3d window to build in VS 2013

OK so here is my source code this is from a tutorial i found online in creating your first DX window. so i copied it by typing it out to try and remember better. Anyways the problem i am having is that I cannot get the program to build in VS, I have tried changing the Linker subsystem to windows, didnt work.
ERROR Recieved
1>MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain#16 referenced in function ___tmainCRTStartup
1>e:\documents\visual studio 2013\Projects\Project1\Debug\Project1.exe : fatal error LNK1120: 1 unresolved externals
Heres external link to code https://gist.github.com/bANNji/24ebedaf5a72f2003d29
//include the basic windows header files and the Direct3dD Header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
// Include the DIrect3D library file
#pragma comment (lib, "d3d9.lib")
// global declarations
LPDIRECT3D9 d3d; // The pointer to our Direct3D Interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
// functiuon prototypes
void initD3D(HWND hWnd); // Sets up and initializes Direct3D
void render_frame(void); // Renders a single frame
void cleanD3D(void); // Closes Direct3D and releases memory
// The window proc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// this function initializes and prepares direct3d for use
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION); // Create the Direct3D Interface
D3DPRESENT_PARAMETERS d3dpp; // create a stuct to hold verious device information
ZeroMemory(&d3dpp, sizeof(d3dpp)); //Clear out the stuct for usee
d3dpp.Windowed = TRUE; // Program windowed not full screen
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // Discard old frames
d3dpp.hDeviceWindow = hWnd; // Set the window to be used by Direct3D
// Create a deviced calss using this information and information from the d3dpp stuct
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
}
// THE FUN STUFF
// this is the function used to render a single frame
void render_frame(void)
{
// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev->BeginScene(); // this begins the 3D Scene
// do 3D Rendering on the back buffer here...
d3ddev->EndScene(); // ends the 3D Scene
d3ddev->Present(NULL, NULL, NULL, NULL); // This displays the created frame
}
// THis is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
d3ddev->Release(); // close and release the 3D Device
d3d->Release(); //Close and release Direct3D
}
The error means exactly what it says: You don't have a WinMain. I would strongly suggest you first learn how to wield the Win32 API to create and manipulate windows by themselves before you try to use them with Direct3D. It is heavily documented on MSDN and pretty easy to grasp. Here's a quick jumble of sample code (incomplete, obviously) to help give you a reference point to get started:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HRESULT hr = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
WNDCLASSEX wndClass;
ZeroMemory(&wndClass,sizeof(wndClass));
wndClass.cbSize = sizeof(wndClass);
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hbrBackground = NULL;
wndClass.hCursor = LoadCursor(hInstance,LoadCursor(NULL,IDC_ARROW);
wndClass.hIcon = LoadIcon(hInstance,LoadIcon(NULL,IDI_APPLICATION);
wndClass.hIconSm = LoadIcon(hInstance,LoadIcon(NULL,IDI_APPLICATION);
wndClass.hInstance = hInstance;
wndClass.lpszMenuName = NULL;
wndClass.lpfnWndProc = winProc;
wndClass.lpszClassName = "derp";
wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wndClass);
RECT win = {0,0,width,height};
AdjustWindowRectEx(&win,flags,FALSE,WS_EX_APPWINDOW);
int winWidth = win.right - win.left;
int winHeight = win.bottom - win.top;
hWnd = CreateWindowEx( WS_EX_APPWINDOW,
"derp",
"derpderp",
flags | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
GetSystemMetrics(SM_CXSCREEN)/2 - width/2,
GetSystemMetrics(SM_CYSCREEN)/2 - height/2,
winWidth,
winHeight,
HWND_DESKTOP,
NULL,
hInstance,
NULL
);
SetWindowPos( hWnd,
HWND_NOTOPMOST,
(GetSystemMetrics(SM_CXSCREEN)/2) - (winWidth/2),
(GetSystemMetrics(SM_CYSCREEN)/2) - (winHeight/2),
winWidth,
winHeight,
SWP_SHOWWINDOW
);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
/* Do your other stuff here */
return 0;
}
And the winproc definition:
LRESULT CALLBACK App::WinProc( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam )
{
switch(uMsg)
{
// NOTE: Obviously you'd need only those that matter to you, and you'd need to fill them in
case WM_KEYUP:
case WM_KEYDOWN:
case WM_CHAR:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
case WM_RBUTTONUP:
case WM_MOUSEMOVE:
case WM_SYSKEYDOWN:
case WM_MOUSEWHEEL:
case WM_ACTIVATE:
case WM_SYSKEYUP:
case WM_SYSCOMMAND:
case WM_CREATE:
case WM_CLOSE:
case WM_DESTROY:
App::GetInstance()->Shutdown();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
return 0;
}

The procedure entry point could not be located in the dynamic link library

I'm trying to proxy ddraw.dll for a game I'm working on (Not for cheating purposes), There are two functions called by the main game in order for it to start:
DirectDrawEnumerateExA
DirectDrawCreateEx
I've added both of these to my C++ project plus done countless amount of research online and I've have got nowhere so far, I've tried various tutorials and various methods such as using a .def file, I can't seem to figure out what is wrong.
When launching the game I get "The procedure entry point DirectDrawEnumerateExA could not be located in the dynamic link library DDRAW.dll"
Here is the code base I'm currently using:
#include <windows.h>
#include <ddraw.h>
typedef HRESULT (WINAPI* DirectDrawEnumerateExA_td)(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
typedef HRESULT (WINAPI* DirectDrawCreateEx_td)(GUID FAR *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkouter);
static struct
{
HMODULE hGameDLL;
char* pGameDLL;
// entry points
DirectDrawEnumerateExA_td OldDirectDrawEnumerateExA;
DirectDrawCreateEx_td OldDirectDrawCreateEx;
} g_state;
extern "C" HRESULT __declspec(dllexport) OldDirectDrawEnumerateExA(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
{
return g_state.OldDirectDrawEnumerateExA(lpCallback, lpContext, dwFlags);
}
extern "C" HRESULT __declspec(dllexport) WINAPI OldDirectDrawCreateEx(GUID FAR *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkouter)
{
return g_state.OldDirectDrawCreateEx(lpGuid, lplpDD, iid, pUnkouter);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if(fdwReason == DLL_PROCESS_ATTACH)
{
char infoBuf[MAX_PATH];
GetSystemDirectory(infoBuf, MAX_PATH);
strcat_s(infoBuf, MAX_PATH, "\\ddraw.dll");
g_state.hGameDLL = LoadLibrary(infoBuf);
g_state.pGameDLL = (char*)g_state.hGameDLL;
if(!g_state.hGameDLL)
{
MessageBox(NULL, "Unable to load ddraw.dll", "Error", MB_OK | MB_ICONEXCLAMATION);
ExitProcess(0);
}
g_state.OldDirectDrawEnumerateExA = (DirectDrawEnumerateExA_td)GetProcAddress(g_state.hGameDLL, "DirectDrawEnumerateExA");
if(!g_state.OldDirectDrawEnumerateExA)
{
MessageBox(NULL, "Unable to find entry point: DirectDrawEnumerateExA", "Error", MB_OK | MB_ICONEXCLAMATION);
ExitProcess(0);
}
g_state.OldDirectDrawCreateEx = (DirectDrawCreateEx_td)GetProcAddress(g_state.hGameDLL, "DirectDrawCreateEx");
if(!g_state.OldDirectDrawCreateEx)
{
MessageBox(NULL, "Unable to find entry point: DirectDrawCreateEX", "Error", MB_OK | MB_ICONEXCLAMATION);
}
MessageBox(NULL, "Test.", "Test Box", MB_OK | MB_ICONEXCLAMATION);
}
else if(fdwReason == DLL_PROCESS_DETACH)
{
if (g_state.hGameDLL)
{
FreeLibrary(g_state.hGameDLL);
}
}
return TRUE;
}
One big issue is the call to LoaLibrary when DLL_PROCESS_ATTACH is taking place. Never do that! Instead, take a look at the Best Practices for Creating DLLs and correct this. The failure you are experimenting has to do with the side effect of calling LoadLibrary when the Loader has not yet finished to attach the DLL to the process.

Starting a thread in a Windows CE 6.0 service

I am developing a Windows Service under Windows CE 6.0. The project produces a DLL, which gets integrated in OS Image. The service gets started, when the WinCE boots thanks to registry settings.
The problem is that I am not able to start the "Thread1" thread. I should see the MessageBox, but there is nothing on the screen. Why? Putting the MessageBox into SFC_Init works fine.
Another thing - when I type "services list" in the console (in the WinCE system), the state of my service is unknown... Why is that so?
Please help!
// SrvForCom.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
HINSTANCE hInst;
// main entry point of the DLL
BOOL WINAPI DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hInst = (HINSTANCE)hModule;
switch(ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls((HMODULE)hModule);
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// function called during initialization process
DWORD SFC_Init(DWORD dwContext) {
PSRVCONTEXT pSrv;
HANDLE hThrd;
DWORD err = ERROR_INVALID_PARAMETER;
// fill the info structure
pSrv->servState = SERVICE_STATE_UNKNOWN;
switch (dwContext) {
case SERVICE_INIT_STARTED:
pSrv->servState = SERVICE_STATE_ON;
break;
case SERVICE_INIT_STOPPED:
pSrv->servState = SERVICE_STATE_OFF;
break;
}
// start new thread
hThrd = CreateThread (NULL, 0, Thread1, NULL, 0, NULL);
if (hThrd) {
CloseHandle (hThrd);
err = 0;
} else {
err = GetLastError();
}
return hThrd;
}
BOOL SFC_Deinit(DWORD dwData) {
return TRUE;
}
BOOL SFC_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
PSRVCONTEXT pSrv = (PSRVCONTEXT)dwData;
return (DWORD)pSrv;
}
BOOL SFC_Close(DWORD dwData) {
return 1;
}
BOOL SFC_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut) {
PSRVCONTEXT pSrv = (PSRVCONTEXT)dwData;
switch (dwCode) {
case IOCTL_SERVICE_STATUS:
*pBufOut = pSrv->servState;
break;
}
return 1;
}
DWORD WINAPI Thread1(LPVOID lpv) {
MessageBox (NULL, TEXT ("The thread has been successfully started!"), TEXT ("Info"), MB_OK);
return 0;
}
I have found answer to this question. The code above is correct apart from one detail - uninitialized structure. "pSrv" is a pointer (type PSRVCONTEXT) to a struct SRVCONTEXT with "servState" field. When executing "pSrv->servState = SERVICE_STATE_UNKNOWN;" some part of the memmory was overwritten, causing errors in the application.
The solution is to first allocate the memmory to this structure before using it:
pSrv = (PSRVCONTEXT)LocalAlloc (LPTR, sizeof (SRVCONTEXT));
After adding above line to my application, everything started working fine. The thread properly started and the service's state changed to "Running".
P.S. The structure looks like this:
typedef struct {
DWORD servState;
} SRVCONTEXT, *PSRVCONTEXT;

Hook CreateFileW

I want to know what are the files opened/access by a process. May i know how to do that? I tried to use Deviare, a free hooking api to help me, but was unable to find any useful information from their AIP lib or forum.
I only know i have to hook on to kernel32.dll and createFileW and i am not sure of how to continue.
Pls help me. Thanks in advance.
It's right. You have to hook the function CreateFileA/W in kernel32.dll to monitor the acces. Do you want to hook these APIs in your own process or in an other process?
If you want to hook functions in your own process you can use
void *DetourFunc(BYTE *src, const BYTE *dst, const int len)
{
BYTE *jmp = (BYTE*)malloc(5+len);
DWORD dwback;
VirtualProtect(src,len,PAGE_READWRITE,&dwback);
memcpy(jmp,src,len);
jmp += len;
jmp[0] = 0xE9;
*(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
src[0] = 0xE9;
*(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
VirtualProtect(src,len,dwback,&dwback);
return (jmp-len);
}
for it. These function detours the function src (f.e. MessageBoxA()) to function dst. As len you can use 5. It returns a function pointer to the original function.
An example call:
typedef int (WINAPI *__MessageBox)(
__in_opt HWND hWnd,
__in_opt LPCTSTR lpText,
__in_opt LPCTSTR lpCaption,
__in UINT uType
);
__MessageBox _MessageBox;
int cMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
//here you can change anything you want
return _MessageBox(hWnd,lpText,lpCaption,uType);
}
int main(void)
{
BYTE *hookfunc = (BYTE*)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA");
_MessageBox = (__MessageBox)DetourFunc(hookfunc,(BYTE*)cMessageBox,5);
return 0;
}
That's an usermode hook. If you want to do this systemwide I would use a device driver. Here is a tutorial about this. http://www.codeproject.com/KB/system/driverdev.aspx
And if you are using VC++ compile in multibyte mode ;).
If you want to hook in an other process just google DLL-Injection ;).

Resources