2 ** SQLite Database Driver
3 ** Copyright (C) 2005-2016 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "sqlitedrv.h"
25 DECLARE_DRIVER_HEADER("SQLITE")
28 * Get error message from connection
30 static void GetErrorMessage(sqlite3
*hdb
, WCHAR
*errorText
)
32 if (errorText
== NULL
)
36 wcsncpy(errorText
, (const WCHAR
*)sqlite3_errmsg16(hdb
), DBDRV_MAX_ERROR_TEXT
);
38 MultiByteToWideChar(CP_UTF8
, 0, sqlite3_errmsg(hdb
), -1, errorText
, DBDRV_MAX_ERROR_TEXT
);
40 errorText
[DBDRV_MAX_ERROR_TEXT
- 1] = 0;
41 RemoveTrailingCRLFW(errorText
);
45 * Prepare string for using in SQL query - enclose in quotes and escape as needed
47 extern "C" char EXPORT
*DrvPrepareStringA(const char *str
)
49 int len
= (int)strlen(str
) + 3; // + two quotes and \0 at the end
50 int bufferSize
= len
+ 128;
51 char *out
= (char *)malloc(bufferSize
);
54 const char *src
= str
;
56 for(outPos
= 1; *src
!= 0; src
++)
61 if (len
>= bufferSize
)
64 out
= (char *)realloc(out
, bufferSize
);
81 * Prepare string for using in SQL query - enclose in quotes and escape as needed
83 extern "C" WCHAR EXPORT
*DrvPrepareStringW(const WCHAR
*str
)
85 int len
= (int)wcslen(str
) + 3; // + two quotes and \0 at the end
86 int bufferSize
= len
+ 128;
87 WCHAR
*out
= (WCHAR
*)malloc(bufferSize
* sizeof(WCHAR
));
90 const WCHAR
*src
= str
;
92 for(outPos
= 1; *src
!= 0; src
++)
97 if (len
>= bufferSize
)
100 out
= (WCHAR
*)realloc(out
, bufferSize
* sizeof(WCHAR
));
102 out
[outPos
++] = L
'\'';
103 out
[outPos
++] = L
'\'';
107 out
[outPos
++] = *src
;
110 out
[outPos
++] = L
'\'';
119 extern "C" bool EXPORT
DrvInit(const char *cmdLine
)
121 if (!sqlite3_threadsafe() || // Fail if SQLite compiled without threading support
122 (sqlite3_initialize() != SQLITE_OK
))
124 sqlite3_enable_shared_cache(1);
125 nxlog_debug(1, _T("SQLite version %hs"), sqlite3_libversion());
132 extern "C" void EXPORT
DrvUnload()
138 * Connect to database
140 extern "C" DBDRV_CONNECTION EXPORT
DrvConnect(const char *host
, const char *login
,
141 const char *password
, const char *database
, const char *schema
, WCHAR
*errorText
)
146 if (sqlite3_open_v2(database
, &hdb
, SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE
, NULL
) == SQLITE_OK
)
148 sqlite3_busy_timeout(hdb
, 30000); // 30 sec. busy timeout
151 pConn
= (SQLITE_CONN
*)malloc(sizeof(SQLITE_CONN
));
152 memset(pConn
, 0, sizeof(SQLITE_CONN
));
154 pConn
->mutexQueryLock
= MutexCreate();
156 sqlite3_exec(hdb
, "PRAGMA foreign_keys = ON", NULL
, NULL
, NULL
);
160 GetErrorMessage(hdb
, errorText
);
164 return (DBDRV_CONNECTION
)pConn
;
168 * Disconnect from database
170 extern "C" void EXPORT
DrvDisconnect(SQLITE_CONN
*hConn
)
175 sqlite3_close(hConn
->pdb
);
176 MutexDestroy(hConn
->mutexQueryLock
);
183 extern "C" DBDRV_STATEMENT EXPORT
DrvPrepare(SQLITE_CONN
*hConn
, WCHAR
*pwszQuery
, DWORD
*pdwError
, WCHAR
*errorText
)
185 char *pszQueryUTF8
= UTF8StringFromWideString(pwszQuery
);
186 MutexLock(hConn
->mutexQueryLock
);
190 int rc
= sqlite3_prepare_v2(hConn
->pdb
, pszQueryUTF8
, -1, &stmt
, NULL
);
191 if ((rc
== SQLITE_LOCKED
) || (rc
== SQLITE_LOCKED_SHAREDCACHE
))
193 // database locked by another thread, retry in 10 milliseconds
197 else if (rc
!= SQLITE_OK
)
199 GetErrorMessage(hConn
->pdb
, errorText
);
201 *pdwError
= DBERR_OTHER_ERROR
;
203 MutexUnlock(hConn
->mutexQueryLock
);
209 * Bind parameter to statement
211 extern "C" void EXPORT
DrvBind(sqlite3_stmt
*stmt
, int pos
, int sqlType
, int cType
, void *buffer
, int allocType
)
215 case DB_CTYPE_STRING
:
217 sqlite3_bind_text16(stmt
, pos
, buffer
, (int)wcslen((WCHAR
*)buffer
) * sizeof(WCHAR
),
218 (allocType
== DB_BIND_STATIC
) ? SQLITE_STATIC
: ((allocType
== DB_BIND_DYNAMIC
) ? free
: SQLITE_TRANSIENT
));
221 char *utf8String
= UTF8StringFromWideString((WCHAR
*)buffer
);
222 sqlite3_bind_text(stmt
, pos
, utf8String
, strlen(utf8String
), free
);
223 if (allocType
== DB_BIND_DYNAMIC
)
228 case DB_CTYPE_UTF8_STRING
:
229 sqlite3_bind_text(stmt
, pos
, (char *)buffer
, strlen((char *)buffer
),
230 (allocType
== DB_BIND_STATIC
) ? SQLITE_STATIC
: ((allocType
== DB_BIND_DYNAMIC
) ? free
: SQLITE_TRANSIENT
));
233 case DB_CTYPE_UINT32
:
234 sqlite3_bind_int(stmt
, pos
, *((int *)buffer
));
235 if (allocType
== DB_BIND_DYNAMIC
)
239 case DB_CTYPE_UINT64
:
240 sqlite3_bind_int64(stmt
, pos
, *((sqlite3_int64
*)buffer
));
241 if (allocType
== DB_BIND_DYNAMIC
)
244 case DB_CTYPE_DOUBLE
:
245 sqlite3_bind_double(stmt
, pos
, *((double *)buffer
));
246 if (allocType
== DB_BIND_DYNAMIC
)
250 if (allocType
== DB_BIND_DYNAMIC
)
257 * Execute prepared statement
259 extern "C" DWORD EXPORT
DrvExecute(SQLITE_CONN
*hConn
, sqlite3_stmt
*stmt
, WCHAR
*errorText
)
263 MutexLock(hConn
->mutexQueryLock
);
265 int rc
= sqlite3_step(stmt
);
266 if ((rc
== SQLITE_DONE
) || (rc
== SQLITE_ROW
))
268 if (sqlite3_reset(stmt
) == SQLITE_OK
)
270 result
= DBERR_SUCCESS
;
274 GetErrorMessage(hConn
->pdb
, errorText
);
275 result
= DBERR_OTHER_ERROR
;
278 else if ((rc
== SQLITE_LOCKED
) || (rc
== SQLITE_LOCKED_SHAREDCACHE
))
280 // database locked by another thread, retry in 10 milliseconds
287 GetErrorMessage(hConn
->pdb
, errorText
);
288 result
= DBERR_OTHER_ERROR
;
292 MutexUnlock(hConn
->mutexQueryLock
);
297 * Destroy prepared statement
299 extern "C" void EXPORT
DrvFreeStatement(sqlite3_stmt
*stmt
)
302 sqlite3_finalize(stmt
);
308 static DWORD
DrvQueryInternal(SQLITE_CONN
*pConn
, const char *pszQuery
, WCHAR
*errorText
)
312 MutexLock(pConn
->mutexQueryLock
);
314 int rc
= sqlite3_exec(pConn
->pdb
, pszQuery
, NULL
, NULL
, NULL
);
317 result
= DBERR_SUCCESS
;
319 else if ((rc
== SQLITE_LOCKED
) || (rc
== SQLITE_LOCKED_SHAREDCACHE
))
321 // database locked by another thread, retry in 10 milliseconds
327 GetErrorMessage(pConn
->pdb
, errorText
);
328 result
= DBERR_OTHER_ERROR
;
330 MutexUnlock(pConn
->mutexQueryLock
);
335 * Perform non-SELECT query
337 extern "C" DWORD EXPORT
DrvQuery(SQLITE_CONN
*pConn
, WCHAR
*pwszQuery
, WCHAR
*errorText
)
342 pszQueryUTF8
= UTF8StringFromWideString(pwszQuery
);
343 dwResult
= DrvQueryInternal(pConn
, pszQueryUTF8
, errorText
);
351 static int SelectCallback(void *pArg
, int nCols
, char **ppszData
, char **ppszNames
)
353 int i
, nPos
, nMaxCol
;
355 if (((SQLITE_RESULT
*)pArg
)->nCols
== 0)
357 ((SQLITE_RESULT
*)pArg
)->nCols
= nCols
;
362 nMaxCol
= min(((SQLITE_RESULT
*)pArg
)->nCols
, nCols
);
365 // Store column names
366 if ((((SQLITE_RESULT
*)pArg
)->ppszNames
== NULL
) && (nCols
> 0) && (ppszNames
!= NULL
))
368 ((SQLITE_RESULT
*)pArg
)->ppszNames
= (char **)malloc(sizeof(char *) * nCols
);
369 for(i
= 0; i
< nCols
; i
++)
370 ((SQLITE_RESULT
*)pArg
)->ppszNames
[i
] = strdup(ppszNames
[i
]);
373 nPos
= ((SQLITE_RESULT
*)pArg
)->nRows
* ((SQLITE_RESULT
*)pArg
)->nCols
;
374 ((SQLITE_RESULT
*)pArg
)->nRows
++;
375 ((SQLITE_RESULT
*)pArg
)->ppszData
= (char **)realloc(((SQLITE_RESULT
*)pArg
)->ppszData
,
376 sizeof(char *) * ((SQLITE_RESULT
*)pArg
)->nCols
* ((SQLITE_RESULT
*)pArg
)->nRows
);
378 for(i
= 0; i
< nMaxCol
; i
++, nPos
++)
379 ((SQLITE_RESULT
*)pArg
)->ppszData
[nPos
] = strdup(CHECK_NULL_EX_A(ppszData
[i
]));
380 for(; i
< ((SQLITE_RESULT
*)pArg
)->nCols
; i
++, nPos
++)
381 ((SQLITE_RESULT
*)pArg
)->ppszData
[nPos
] = strdup("");
386 * Free SELECT results
388 extern "C" void EXPORT
DrvFreeResult(SQLITE_RESULT
*hResult
)
394 if (hResult
->ppszData
!= NULL
)
396 nCount
= hResult
->nRows
* hResult
->nCols
;
397 for(i
= 0; i
< nCount
; i
++)
398 safe_free(hResult
->ppszData
[i
]);
399 free(hResult
->ppszData
);
401 for(i
= 0; i
< hResult
->nCols
; i
++)
402 safe_free(hResult
->ppszNames
[i
]);
403 free(hResult
->ppszNames
);
410 * Perform SELECT query
412 extern "C" DBDRV_RESULT EXPORT
DrvSelect(SQLITE_CONN
*hConn
, WCHAR
*pwszQuery
, DWORD
*pdwError
, WCHAR
*errorText
)
414 char *pszQueryUTF8
= UTF8StringFromWideString(pwszQuery
);
416 SQLITE_RESULT
*result
= (SQLITE_RESULT
*)malloc(sizeof(SQLITE_RESULT
));
417 memset(result
, 0, sizeof(SQLITE_RESULT
));
419 MutexLock(hConn
->mutexQueryLock
);
421 int rc
= sqlite3_exec(hConn
->pdb
, pszQueryUTF8
, SelectCallback
, result
, NULL
);
422 if ((rc
== SQLITE_LOCKED
) || (rc
== SQLITE_LOCKED_SHAREDCACHE
))
424 // database locked by another thread, retry in 10 milliseconds
428 else if (rc
!= SQLITE_OK
)
430 GetErrorMessage(hConn
->pdb
, errorText
);
431 DrvFreeResult(result
);
434 MutexUnlock(hConn
->mutexQueryLock
);
437 *pdwError
= (result
!= NULL
) ? DBERR_SUCCESS
: DBERR_OTHER_ERROR
;
442 * Perform SELECT query using prepared statement
444 extern "C" DBDRV_RESULT EXPORT
DrvSelectPrepared(SQLITE_CONN
*hConn
, sqlite3_stmt
*stmt
, DWORD
*pdwError
, WCHAR
*errorText
)
446 SQLITE_RESULT
*result
= (SQLITE_RESULT
*)malloc(sizeof(SQLITE_RESULT
));
447 memset(result
, 0, sizeof(SQLITE_RESULT
));
449 MutexLock(hConn
->mutexQueryLock
);
451 int nCols
= sqlite3_column_count(stmt
);
452 char **cnames
= (char **)malloc(sizeof(char *) * nCols
* 2); // column names + values
453 char **values
= &cnames
[nCols
];
454 bool firstRow
= true;
457 int rc
= sqlite3_step(stmt
);
459 if (firstRow
&& ((rc
== SQLITE_LOCKED
) || (rc
== SQLITE_LOCKED_SHAREDCACHE
)))
461 // database locked by another thread, retry in 10 milliseconds
467 if (((rc
== SQLITE_DONE
) || (rc
== SQLITE_ROW
)) && firstRow
)
470 for(int i
= 0; i
< nCols
; i
++)
471 cnames
[i
] = (char *)sqlite3_column_name(stmt
, i
);
474 if (rc
== SQLITE_ROW
)
476 for(int i
= 0; i
< nCols
; i
++)
477 values
[i
] = (char *)sqlite3_column_text(stmt
, i
);
478 SelectCallback(result
, nCols
, values
, cnames
);
480 else if (rc
== SQLITE_DONE
)
482 *pdwError
= DBERR_SUCCESS
;
487 GetErrorMessage(hConn
->pdb
, errorText
);
488 *pdwError
= DBERR_OTHER_ERROR
;
494 if (*pdwError
== DBERR_SUCCESS
)
496 if (sqlite3_reset(stmt
) != SQLITE_OK
)
498 GetErrorMessage(hConn
->pdb
, errorText
);
499 *pdwError
= DBERR_OTHER_ERROR
;
507 MutexUnlock(hConn
->mutexQueryLock
);
509 if (*pdwError
!= DBERR_SUCCESS
)
511 DrvFreeResult(result
);
519 * Get field length from result
521 extern "C" LONG EXPORT
DrvGetFieldLength(DBDRV_RESULT hResult
, int iRow
, int iColumn
)
523 if ((iRow
< ((SQLITE_RESULT
*)hResult
)->nRows
) &&
524 (iColumn
< ((SQLITE_RESULT
*)hResult
)->nCols
) &&
525 (iRow
>= 0) && (iColumn
>= 0))
526 return (LONG
)strlen(((SQLITE_RESULT
*)hResult
)->ppszData
[iRow
* ((SQLITE_RESULT
*)hResult
)->nCols
+ iColumn
]);
531 * Get field value from result
533 extern "C" WCHAR EXPORT
*DrvGetField(DBDRV_RESULT hResult
, int iRow
, int iColumn
, WCHAR
*pwszBuffer
, int nBufLen
)
535 if ((iRow
< ((SQLITE_RESULT
*)hResult
)->nRows
) &&
536 (iColumn
< ((SQLITE_RESULT
*)hResult
)->nCols
) &&
537 (iRow
>= 0) && (iColumn
>= 0))
539 MultiByteToWideChar(CP_UTF8
, 0, ((SQLITE_RESULT
*)hResult
)->ppszData
[iRow
* ((SQLITE_RESULT
*)hResult
)->nCols
+ iColumn
],
540 -1, pwszBuffer
, nBufLen
);
541 pwszBuffer
[nBufLen
- 1] = 0;
548 * Get field value from result as UTF8 string
550 extern "C" char EXPORT
*DrvGetFieldUTF8(DBDRV_RESULT hResult
, int iRow
, int iColumn
, char *buffer
, int nBufLen
)
552 if ((iRow
< ((SQLITE_RESULT
*)hResult
)->nRows
) &&
553 (iColumn
< ((SQLITE_RESULT
*)hResult
)->nCols
) &&
554 (iRow
>= 0) && (iColumn
>= 0))
556 strncpy(buffer
, ((SQLITE_RESULT
*)hResult
)->ppszData
[iRow
* ((SQLITE_RESULT
*)hResult
)->nCols
+ iColumn
], nBufLen
);
557 buffer
[nBufLen
- 1] = 0;
564 * Get number of rows in result
566 extern "C" int EXPORT
DrvGetNumRows(SQLITE_RESULT
*hResult
)
568 return hResult
->nRows
;
572 * Get column count in query result
574 extern "C" int EXPORT
DrvGetColumnCount(SQLITE_RESULT
*hResult
)
576 return (hResult
!= NULL
) ? hResult
->nCols
: 0;
580 * Get column name in query result
582 extern "C" const char EXPORT
*DrvGetColumnName(SQLITE_RESULT
*hResult
, int column
)
586 if ((column
>= 0) && (column
< hResult
->nCols
))
588 pszRet
= hResult
->ppszNames
[column
];
594 * Perform unbuffered SELECT query
596 extern "C" DBDRV_UNBUFFERED_RESULT EXPORT
DrvSelectUnbuffered(SQLITE_CONN
*hConn
, WCHAR
*pwszQuery
, DWORD
*pdwError
, WCHAR
*errorText
)
598 SQLITE_UNBUFFERED_RESULT
*result
;
602 pszQueryUTF8
= UTF8StringFromWideString(pwszQuery
);
603 MutexLock(hConn
->mutexQueryLock
);
605 int rc
= sqlite3_prepare(hConn
->pdb
, pszQueryUTF8
, -1, &stmt
, NULL
);
608 result
= (SQLITE_UNBUFFERED_RESULT
*)malloc(sizeof(SQLITE_UNBUFFERED_RESULT
));
609 result
->connection
= hConn
;
611 result
->prepared
= false;
612 *pdwError
= DBERR_SUCCESS
;
614 else if ((rc
== SQLITE_LOCKED
) || (rc
== SQLITE_LOCKED_SHAREDCACHE
))
616 // database locked by another thread, retry in 10 milliseconds
622 GetErrorMessage(hConn
->pdb
, errorText
);
623 MutexUnlock(hConn
->mutexQueryLock
);
625 *pdwError
= DBERR_OTHER_ERROR
;
632 * Perform unbuffered SELECT query using prepared statement
634 extern "C" DBDRV_UNBUFFERED_RESULT EXPORT
DrvSelectPreparedUnbuffered(SQLITE_CONN
*hConn
, sqlite3_stmt
*stmt
, DWORD
*pdwError
, WCHAR
*errorText
)
636 if ((hConn
== NULL
) || (stmt
== NULL
))
639 SQLITE_UNBUFFERED_RESULT
*result
= (SQLITE_UNBUFFERED_RESULT
*)malloc(sizeof(SQLITE_UNBUFFERED_RESULT
));
640 result
->connection
= hConn
;
642 result
->prepared
= true;
643 *pdwError
= DBERR_SUCCESS
;
648 * Fetch next result line from asynchronous SELECT results
650 extern "C" bool EXPORT
DrvFetch(SQLITE_UNBUFFERED_RESULT
*result
)
656 int rc
= sqlite3_step(result
->stmt
);
657 if (rc
== SQLITE_ROW
)
659 result
->numColumns
= sqlite3_column_count(result
->stmt
);
662 else if ((rc
== SQLITE_LOCKED
) || (rc
== SQLITE_LOCKED_SHAREDCACHE
))
664 // database locked by another thread, retry in 10 milliseconds
666 sqlite3_reset(result
->stmt
);
673 * Get field length from unbuffered query result
675 extern "C" LONG EXPORT
DrvGetFieldLengthUnbuffered(SQLITE_UNBUFFERED_RESULT
*result
, int iColumn
)
677 if ((iColumn
>= 0) && (iColumn
< result
->numColumns
))
678 return (LONG
)strlen((char *)sqlite3_column_text(result
->stmt
, iColumn
));
683 * Get field from current row in unbuffered query result
685 extern "C" WCHAR EXPORT
*DrvGetFieldUnbuffered(SQLITE_UNBUFFERED_RESULT
*result
, int iColumn
, WCHAR
*pBuffer
, int iBufSize
)
688 WCHAR
*pwszRet
= NULL
;
690 if ((iColumn
>= 0) && (iColumn
< result
->numColumns
))
692 pszData
= (char *)sqlite3_column_text(result
->stmt
, iColumn
);
695 MultiByteToWideChar(CP_UTF8
, 0, pszData
, -1, pBuffer
, iBufSize
);
696 pBuffer
[iBufSize
- 1] = 0;
704 * Get field from current row in unbuffered query result as UTF-8 string
706 extern "C" char EXPORT
*DrvGetFieldUnbufferedUTF8(SQLITE_UNBUFFERED_RESULT
*result
, int iColumn
, char *pBuffer
, int iBufSize
)
711 if ((iColumn
>= 0) && (iColumn
< result
->numColumns
))
713 pszData
= (char *)sqlite3_column_text(result
->stmt
, iColumn
);
716 strncpy(pBuffer
, pszData
, iBufSize
);
717 pBuffer
[iBufSize
- 1] = 0;
725 * Get column count in async query result
727 extern "C" int EXPORT
DrvGetColumnCountUnbuffered(SQLITE_UNBUFFERED_RESULT
*result
)
729 return (result
!= NULL
) ? result
->numColumns
: 0;
733 * Get column name in async query result
735 extern "C" const char EXPORT
*DrvGetColumnNameUnbuffered(SQLITE_UNBUFFERED_RESULT
*result
, int column
)
737 const char *pszRet
= NULL
;
739 if ((column
>= 0) && (column
< result
->numColumns
))
741 pszRet
= sqlite3_column_name(result
->stmt
, column
);
747 * Destroy result of async query
749 extern "C" void EXPORT
DrvFreeUnbufferedResult(SQLITE_UNBUFFERED_RESULT
*result
)
753 if (result
->prepared
)
754 sqlite3_reset(result
->stmt
);
756 sqlite3_finalize(result
->stmt
);
757 MutexUnlock(result
->connection
->mutexQueryLock
);
765 extern "C" DWORD EXPORT
DrvBegin(SQLITE_CONN
*pConn
)
767 return DrvQueryInternal(pConn
, "BEGIN IMMEDIATE", NULL
);
773 extern "C" DWORD EXPORT
DrvCommit(SQLITE_CONN
*pConn
)
775 return DrvQueryInternal(pConn
, "COMMIT", NULL
);
779 * Rollback transaction
781 extern "C" DWORD EXPORT
DrvRollback(SQLITE_CONN
*pConn
)
783 return DrvQueryInternal(pConn
, "ROLLBACK", NULL
);
787 * Check if table exist
789 extern "C" int EXPORT
DrvIsTableExist(SQLITE_CONN
*pConn
, const WCHAR
*name
)
792 swprintf(query
, 256, L
"SELECT count(*) FROM sqlite_master WHERE type='table' AND upper(name)=upper('%ls')", name
);
794 WCHAR errorText
[DBDRV_MAX_ERROR_TEXT
];
795 int rc
= DBIsTableExist_Failure
;
796 SQLITE_RESULT
*hResult
= (SQLITE_RESULT
*)DrvSelect(pConn
, query
, &error
, errorText
);
799 WCHAR buffer
[64] = L
"";
800 DrvGetField(hResult
, 0, 0, buffer
, 64);
801 rc
= (wcstol(buffer
, NULL
, 10) > 0) ? DBIsTableExist_Found
: DBIsTableExist_NotFound
;
802 DrvFreeResult(hResult
);
812 bool WINAPI
DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID lpReserved
)
814 if (dwReason
== DLL_PROCESS_ATTACH
)
815 DisableThreadLibraryCalls(hInstance
);