ODBC lesson
asm-fileinclude win64a.inc
include odbc32.inc
includelib odbc32.lib
IMAGE_BASE equ 400000h
IDD_MAINDLG equ 101
IDR_MAINMENU equ 102
IDC_DATALIST equ 1000
IDM_CONNECT equ 0;40001
IDM_DISCONNECT equ 1;40002
IDM_QUERY equ 2;40003
IDM_CUSTOMQUERY equ 3;40004
IDC_NAME equ 1000
IDC_OK equ 1001
IDC_CANCEL equ 1002
IDD_QUERYDLG equ 102
.code
WinMain proc
push rbp
mov ebp,esp
sub esp,30h
xor ebx,ebx
call GetProgramPath
mov [rsp+20h],rbx
mov r9d,offset DlgProc
xor r8d,r8d
mov edx,IDD_MAINDLG
mov ecx,IMAGE_BASE
call DialogBoxParam
xor ecx,ecx
call ExitProcess
call InitCommonControls
WinMain endp
DlgProc proc hDlg:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
push rbp
mov ebp,esp
sub esp,30h
mov hDlg,rcx
mov wParam,r8
mov lParam,r9
cmp edx,WM_CLOSE
je wmCLOSE
cmp edx,WM_INITDIALOG
je wmINITDIALOG
cmp edx,WM_COMMAND
jne wmBYE
wmCOMMAND:or r9,r9;.if lParam==0
jnz a1
movzx rax,r8w;wParam
jmp handle[rax*8]
CONNECT:;mov rcx,hDlg
call ODBCConnect
jmp wmBYE
DISCONNECT:;mov rcx,hDlg
call ODBCDisconnect
jmp wmBYE
QUERY: ;mov rcx,hDlg
call RunQuery
jmp wmBYE
CUSTOMQUERY:mov qword ptr [rsp+20h], 0
mov r9d, offset QueryProc
mov r8,hDlg
mov edx, IDD_QUERYDLG
mov ecx, IMAGE_BASE
call DialogBoxParam
jmp wmBYE
wmINITDIALOG:
;mov rcx,hDlg
call GetMenu
mov hMenu,rax
mov edx, IDC_DATALIST
mov rcx, hDlg
call GetDlgItem
mov hList,rax
call InsertColumn
jmp wmBYE
wmCLOSE:mov r8d,MF_BYCOMMAND
mov edx, IDM_CONNECT
mov rcx, hMenu
call GetMenuState
cmp eax,MF_GRAYED
jnz @f
mov rcx, hDlg
call ODBCDisconnect
@@: xor edx,edx
mov rcx,hDlg
call EndDialog
wmBYE: xor eax,eax
jmp @f
a1: mov eax,TRUE
@@: leave
retn
handle dq CONNECT,DISCONNECT,QUERY,CUSTOMQUERY
DlgProc endp
GetProgramPath proc
push rdi
sub esp,20h
mov r8d,sizeof ProgPath
mov edx,offset ProgPath
xor ecx,ecx;NULL
call GetModuleFileName
std
mov edi,offset ProgPath
add edi,sizeof ProgPath-1
mov al,"\"
mov ecx,sizeof ProgPath
repne scasb
cld
mov byte ptr [rdi+2],0
add esp,20h
pop rdi
ret
GetProgramPath endp
SwitchMenuState proc Flag:QWORD
push rbp
push rdi
push rsi
mov ebp,esp
sub esp,20h
mov rsi,rcx;mov Flag,rcx
mov ebx,3
mov rdi,hMenu
xor esi,1
@@: mov r8d,esi;MF_ENABLED/MF_GRAYED
mov edx,ebx;IDM_CUSTOMQUERY,IDM_QUERY,IDM_DISCONNECT
mov ecx,edi;hMenu
call EnableMenuItem
dec ebx
jnz @b
xor esi,1
mov r8d,esi;MF_ENABLED/MF_GRAYED
mov edx,ebx;IDM_CUSTOMQUERY,IDM_QUERY,IDM_DISCONNECT
mov ecx,edi;hMenu
call EnableMenuItem
leave
pop rsi
pop rdi
retn
SwitchMenuState endp
ODBCConnect proc hDlg:QWORD
push rbp
mov ebp,esp
sub esp,40h
mov hDlg,rcx
mov r8d, offset hEnv
mov edx, SQL_NULL_HANDLE
mov ecx, SQL_HANDLE_ENV
call SQLAllocHandle
or ax,ax;.if ax==SQL_SUCCESS
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz @0
@@: xor r9d,r9d
mov r8d, SQL_OV_ODBC3
mov edx,SQL_ATTR_ODBC_VERSION
mov rcx, hEnv
call SQLSetEnvAttr
or ax,ax;.if ax==SQL_SUCCESS
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz @1
@@: mov r8d, offset hConn
mov rdx, hEnv
mov ecx, SQL_HANDLE_DBC
call SQLAllocHandle
or ax,ax;.if ax==SQL_SUCCESS
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz @2
@@: mov edx,offset strConnect
mov ecx,offset ConnectString
call lstrcpy
mov edx, offset ProgPath
mov ecx,offset ConnectString
call lstrcat
mov edx,offset DBName
mov ecx, offset ConnectString
call lstrcat
mov qword ptr [rsp+38h], SQL_DRIVER_COMPLETE
db 48h;mov eax,offset StrLen
dd 302444C7h,StrLen;mov [rsp+30h],rax
mov qword ptr [rsp+28h],sizeof Conn
db 48h;mov eax, offset Conn
dd 202444C7h,Conn;mov [rsp+20h],rax
mov r9d, sizeof ConnectString
mov r8d, offset ConnectString
mov rdx, hDlg
mov rcx, hConn
call SQLDriverConnect
or ax,ax;.if ax==SQL_SUCCESS
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz @3
@@: mov ecx,TRUE
call SwitchMenuState
mov r9d,MB_OK+MB_ICONINFORMATION
mov r8d,offset ConnectCaption
mov edx, offset Conn
jmp wmBYE
@3: mov rdx, hConn
mov ecx, SQL_HANDLE_DBC
call SQLFreeHandle
mov rdx, hEnv
mov ecx, SQL_HANDLE_ENV
call SQLFreeHandle
mov r9d, MB_OK+MB_ICONERROR
mov r8d,offset AppName
mov edx, offset ConnFail
jmp wmBYE
@2: mov rdx, hEnv
mov ecx, SQL_HANDLE_ENV
call SQLFreeHandle
mov r9d, MB_OK+MB_ICONERROR
mov r8d, offset AppName
mov edx, offset AllocConnFail
jmp wmBYE
@1: mov rdx, hEnv
mov ecx, SQL_HANDLE_ENV
call SQLFreeHandle
mov r9d, MB_OK+MB_ICONERROR
mov r8d, offset AppName
mov edx, offset SetAttrFail
jmp wmBYE
@0: mov r9d, MB_OK+MB_ICONERROR
mov r8d, offset AppName
mov edx, offset AllocEnvFail
wmBYE: mov rcx, hDlg
call MessageBox
leave
retn
ODBCConnect endp
ODBCDisconnect proc hDlg:QWORD
push rbp
mov ebp,esp
sub esp,20h
mov hDlg,rcx
mov rcx, hConn
call SQLDisconnect
mov rdx, hConn
mov ecx, SQL_HANDLE_DBC
call SQLFreeHandle
mov rdx, hEnv
mov ecx, SQL_HANDLE_ENV
call SQLFreeHandle
xor ecx,ecx;FALSE
call SwitchMenuState
mov edx, SW_HIDE
mov rcx,hList
call ShowWindow
mov r9d,MB_OK+MB_ICONINFORMATION
mov r8d, offset AppName
mov edx,offset Disconnect
mov rcx,hDlg
call MessageBox
leave
retn
ODBCDisconnect endp
InsertColumn proc
LOCAL lvc:LV_COLUMN
push rbp
mov ebp,esp
sub esp,(20h+sizeof LV_COLUMN+15)and(-16)
mov lvc.imask,LVCF_TEXT+LVCF_WIDTH
mov eax,offset Heading1
mov lvc.pszText,rax
mov lvc.lx,150
lea r9d,lvc
xor r8d,r8d
mov edx, LVM_INSERTCOLUMN
mov rcx,hList
call SendMessage
mov eax,offset Heading2
mov lvc.pszText,rax
lea r9d,lvc
mov r8d,1
mov edx, LVM_INSERTCOLUMN
mov rcx,hList
call SendMessage
mov eax,offset Heading3
mov lvc.pszText,rax
lea r9d,lvc
mov r8d,3
mov edx, LVM_INSERTCOLUMN
mov rcx,hList
call SendMessage
leave
retn
InsertColumn endp
FillData proc
LOCAL lvi:LV_ITEM
LOCAL row:QWORD
push rbp
mov ebp,esp
sub esp,(30h+sizeof LV_ITEM+8+15)and(-16)
db 48h;mov eax,offset NameLength
dd 282444C7h,NameLength;mov [rsp+28h],rax
mov qword ptr [rsp+20h], sizeof TheName
mov r9d, offset TheName
mov r8d,SQL_C_CHAR
mov edx,1
mov rcx, hStmt
call SQLBindCol
db 48h;mov eax,offset SurnameLength
dd 282444C7h,SurnameLength;mov [rsp+28h],rax
mov qword ptr [rsp+20h], sizeof TheSurname
mov r9d, offset TheSurname
mov r8d,SQL_C_CHAR
mov edx,1
mov rcx, hStmt
call SQLBindCol
db 48h;mov eax,offset TelNoLength
dd 282444C7h,TelNoLength;mov [rsp+28h],rax
mov qword ptr [rsp+20h], sizeof TelNo
mov r9d, offset TelNo
mov r8d,SQL_C_CHAR
mov edx,1
mov rcx, hStmt
call SQLBindCol
mov row,0
;.while TRUE
@0: mov byte ptr TheName,0
mov byte ptr TheSurname,0
mov byte ptr TelNo,0
mov rcx, hStmt
call SQLFetch
or ax,ax;.if ax==SQL_SUCCESS ||
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz wmBYE
@@: mov lvi.imask,LVIF_TEXT+LVIF_PARAM
mov rax,row
mov lvi.iItem,eax
mov lvi.iSubItem,0
mov eax,offset TheName
mov lvi.pszText,rax
mov rax,row
mov lvi.lParam,eax
lea r9d,lvi
xor r8d,r8d
mov edx, LVM_INSERTITEM
mov rcx,hList
call SendMessage
mov lvi.imask,LVIF_TEXT
inc lvi.iSubItem
mov eax,offset TheSurname
mov lvi.pszText,rax
lea r9d,lvi
xor r8d,r8d
mov edx,LVM_SETITEM
mov rcx,hList
call SendMessage
inc lvi.iSubItem
mov eax,offset TelNo
mov lvi.pszText,rax
lea r9d,lvi
xor r8d,r8d
mov edx,LVM_SETITEM
mov rcx,hList
call SendMessage
inc row
jmp @0;.else
wmBYE: leave
retn
FillData endp
RunQuery proc hDlg:QWORD
push rbp
mov ebp,esp
sub esp,20h
mov hDlg,rcx
mov edx, SW_SHOW
mov rcx, hList
call ShowWindow
xor r9d,r9d
xor r8d,r8d
mov edx, LVM_DELETEALLITEMS
mov rcx, hList
call SendMessage
mov r8d, offset hStmt
mov rdx, hConn
mov ecx, SQL_HANDLE_STMT
call SQLAllocHandle
or ax,ax;.if ax==SQL_SUCCESS ||
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz @0
@@: mov r8d, sizeof SQLStatement
mov edx, offset SQLStatement
mov rcx, hStmt
call SQLExecDirect
cmp ax,ax;.if ax==SQL_SUCCESS ||
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz @1
@@: call FillData
jnz @f;.else
@1: xor edx,edx;mov edx, SW_HIDE
mov rcx, hList
call ShowWindow
mov r9d, MB_OK+MB_ICONERROR
mov r8d, offset AppName
mov edx,offset ExecuteFail
mov rcx,hDlg
call MessageBox
@@: mov rcx, hStmt
call SQLCloseCursor
mov rdx, hStmt
mov ecx, SQL_HANDLE_STMT
call SQLFreeHandle
jmp @f;.else
@0: mov edx, SW_HIDE
mov rcx, hList
call ShowWindow
mov r9d, MB_OK+MB_ICONERROR
mov r8d, offset AppName
mov edx,offset AllocStmtFail
mov rcx,hDlg
call MessageBox
;.endif
@@: leave
retn
RunQuery endp
QueryProc proc hDlg:QWORD, uMsg:QWORD, wParam:QWORD, lParam:QWORD
push rbp
mov ebp,esp
sub esp,50h
mov hDlg,rcx
;mov uMsg,rdx
mov wParam,r8
mov lParam,r9
cmp edx,WM_INITDIALOG
je wmINITDIALOG
cmp edx,WM_COMMAND
je wmCOMMAND
cmp edx,WM_CLOSE
jne @2
wmCLOSE: mov rdx, hStmt
mov edx, SQL_HANDLE_STMT
call SQLFreeHandle
xor edx,edx
mov rcx, hDlg
call EndDialog
jmp wmBYE
wmINITDIALOG:
mov edx, SW_SHOW
mov rcx, hList
call ShowWindow
mov r8d, offset hStmt
mov rdx, hConn
mov ecx, SQL_HANDLE_STMT
call SQLAllocHandle
or ax,ax;.if ax==SQL_SUCCESS ||
jz @f
cmp ax,SQL_SUCCESS_WITH_INFO
jnz @0
@@: mov edx, offset SQLStatement
mov ecx, offset Conn
call lstrcpy
mov edx, offset WhereStatement
mov ecx, offset Conn
call lstrcat
db 48h;mov eax,offset StrLen
dd 482444C7h,StrLen;mov [rsp+48h],rax
mov qword ptr [rsp+40h],25
db 48h;mov eax, offset SearchName
dd 382444C7h,SearchName;mov [rsp+38h],rax
mov qword ptr [rsp+30h],0
mov qword ptr [rsp+28h],25
mov qword ptr [rsp+20h], SQL_CHAR
mov r9d, SQL_C_CHAR
mov r8d, SQL_PARAM_INPUT
mov edx, 1
mov rcx,hStmt
call SQLBindParameter
mov r8d, sizeof Conn
mov edx, offset Conn
mov rcx, hStmt
call SQLPrepare
jmp wmBYE;.else
@0: mov edx, SW_HIDE
mov rcx, hList
call ShowWindow
mov r9d, MB_OK+MB_ICONERROR
mov r8d, offset AppName
mov edx,offset AllocStmtFail
mov rcx,hDlg
call MessageBox
xor edx,edx
mov rcx, hDlg
call EndDialog
jmp wmBYE
wmCOMMAND:
mov rax,r8; wParam
shr eax,16
or eax,eax;.if ax==BN_CLICKED
jnz wmBYE
mov rax,r8;wParam
cmp ax,IDC_OK
jnz @1
mov r9d, 25
mov r8d, offset SearchName
mov edx, IDC_NAME
mov rcx, hDlg
call GetDlgItemText
or ax,ax;.if ax==0
jnz @f
mov r9d, MB_OK+MB_ICONERROR
mov r8d, offset AppName
mov edx,offset NoData
mov rcx, hDlg
call MessageBox
mov edx, IDC_NAME
mov rcx, hDlg
call GetDlgItem
mov ecx, eax
call SetFocus
jmp wmBYE;.else
@@: mov ecx,offset SearchName
call lstrlen
mov StrLen,rax
xor r9d,r9d
xor r8d,r8d
mov edx, LVM_DELETEALLITEMS
mov rcx, hList
call SendMessage
mov rcx, hStmt
call SQLExecute
call FillData
mov rcx, hStmt
call SQLCloseCursor
jmp wmBYE
@1: mov rdx, hStmt
mov edx, SQL_HANDLE_STMT
call SQLFreeHandle
xor edx,edx
mov rcx, hDlg
call EndDialog
jmp wmBYE
@2: xor eax,eax;mov eax,FALSE
jmp @f
wmBYE: mov eax,TRUE
@@: leave
retn
QueryProc endp
;---------------------------------------
hEnv dq ? ; environment handle
hConn dq ? ; connection handle
hStmt dq ?
Conn db 256 dup(?)
StrLen dq ?
hMenu dq ? ; handle to the main menu
hList dq ? ; handle to the listview control
TheName db 26 dup(?)
TheSurname db 26 dup(?)
TelNo db 21 dup(?)
NameLength dq ?
SurnameLength dq ?
TelNoLength dq ?
SearchName db 26 dup(?)
ProgPath db 256 dup(?)
ConnectString db 1024 dup(?)
SQLStatement db "select * from main",0
WhereStatement db " where name=?",0
strConnect db "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=",0
DBName db "test.mdb",0
ConnectCaption db "Complete Connection String",0
Disconnect db "Disconnect successful",0
AppName db "ODBC Test",0
AllocEnvFail db "Environment handle allocation failed",0
AllocConnFail db "Connection handle allocation failed",0
SetAttrFail db "Cannot set desired ODBC version",0
NoData db "You must type the name in the edit box",0
ExecuteFail db "Execution of SQL statement failed",0
ConnFail db "Connection attempt failed",0
AllocStmtFail db "Statement handle allocation failed",0
Heading1 db "Name",0
Heading2 db "Surname",0
Heading3 db "Telephone No.",0
endrc-file#include "resource.h"
#define IDD_MAINDLG 101
#define IDR_MAINMENU 102
#define IDD_QUERYDLG 102
#define IDC_DATALIST 1000
#define IDC_NAME 1000
#define IDC_OK 1001
#define IDC_CANCEL 1002
#define IDM_CONNECT 0
#define IDM_DISCONNECT 1
#define IDM_QUERY 2
#define IDM_CUSTOMQUERY 3
IDD_MAINDLG DIALOGEX 0, 0, 275, 97
STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP |
WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CLIENTEDGE
CAPTION "ODBC Test"
MENU IDR_MAINMENU
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "List1",IDC_DATALIST,"SysListView32",LVS_REPORT |
LVS_SINGLESEL | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP,
7,7,260,82
END
IDD_QUERYDLG DIALOG DISCARDABLE 0, 0, 144, 38
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | DS_CENTER | WS_SYSMENU
CAPTION "Type in the name"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "",IDC_STATIC,7,1,87,30
EDITTEXT IDC_NAME,18,12,66,13,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDC_OK,104,6,33,11
PUSHBUTTON "Cancel",IDC_CANCEL,103,20,33,11
END
IDR_MAINMENU MENU DISCARDABLE
BEGIN
POPUP "&Database"
BEGIN
MENUITEM "&Connect", IDM_CONNECT
MENUITEM "&Disconnect", IDM_DISCONNECT, GRAYED
MENUITEM SEPARATOR
MENUITEM "&View all records", IDM_QUERY, GRAYED
MENUITEM "&Query", IDM_CUSTOMQUERY, GRAYED
END
ENDConnection attempt failed!