<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Delphi</title><link>http://webuc.net/chinahuman/category/184.aspx</link><description>Delphi</description><managingEditor>铁匠</managingEditor><dc:language>af</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>铁匠</dc:creator><title>编程实现SqlServer扩展存储过程并实现Image类型参数的输入和结果的返回</title><link>http://webuc.net/chinahuman/archive/2008/08/30/10105.aspx</link><pubDate>Sat, 30 Aug 2008 10:08:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2008/08/30/10105.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/10105.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2008/08/30/10105.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/10105.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/10105.aspx</trackback:ping><description>&lt;p&gt;SQLServer有一项即将要过时的功能，那就是扩展存储过程（在MSDN上查询该方面的资料的时候，上面都有一个提示说是这个功能将会在以后的SQL版本中删除，建议使用CLR集成）。虽然要过时了，但是看着现在有不少的DB还在用SQL2000说明这个功能至少还有几年有效期。对了，忘了说了扩展存储过程是干啥用的，懒得查最官方的说法了，用我的语言来说，那就是使用自己的开发语言，来实现一些数据库没有实现的功能，比如说我想在数据库里面直接作MD5的加密和解密，这个功能SQL Server本来不具有的，但是可以自己写一个扩展存储过程来实现。&lt;/p&gt; &lt;p&gt;开发扩展存储过程的开发语言还是有些要求的，就是要能实现导出函数的，如C（VC,BCB,其它的C）,Delphi等，C#由于无法实现导出函数，所以就不能开发了，不过他可以开发CLR集成。由于我只会Delphi，所以我就用它来作例子。&lt;/p&gt; &lt;h2&gt;&lt;strong&gt;扩展存储过程的hellowolrd&lt;font color="#ffffff"&gt;（铁匠出品）&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt; &lt;p&gt;如果仅仅写一个hello wolrd，Delphi是不需要任何东西就可以实现，那就是：新建一个DLL的工程，在里面写个如下函数：&lt;/p&gt; &lt;p&gt;function xp_helloWorld: Boolean; stdcall;&lt;br&gt;begin&lt;br&gt;//在这里面可以写一个文件好看到效果，具体的代码我就不写了&lt;br&gt;end;&lt;/p&gt; &lt;p&gt;然后把它放在导出函数里面：&lt;/p&gt; &lt;p&gt;exports&lt;br&gt;xp_helloWorld;&lt;/p&gt; &lt;p&gt;再在SQLSERVER里去注册，注意注册扩展存储过程只能在Master库里实现，还要求操作者有一定的权限,SQL如下：&lt;/p&gt; &lt;p&gt;if exists &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (select * from master.dbo.sysobjects where id = object_id('xp_helloWorld')) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; execute sp_dropextendedproc 'xp_helloWorld'&lt;br&gt;go&lt;br&gt;--我编写的dll在'D:\PersonWork\SQLExtProcedure\目录下面,修改成你的编写的目录&lt;br&gt;execute sp_addextendedproc 'xp_helloWorld', 'D:\PersonWork\SQLExtProcedure\sqlExtProcedure.dll'&lt;br&gt;go &lt;p&gt;然后在写SQL exec Master.dbo.xp_helloWorld就能看到效果了。 &lt;h4&gt;&lt;strong&gt;实用的扩展存储过程&lt;font color="#ffffff"&gt;（铁匠出品）&lt;/font&gt;&lt;/strong&gt;&lt;/h4&gt; &lt;p&gt;但是我们开发东西不是一个helloworld就能够用的，所以我们就得引入新的东西：MsOdsApi，这个是一个我们的代码去调用sql现有功能的入口，因为Sqlserver的SDK并没有给Delphi作个版本，所以我们只好自己辛苦一下来转换他们的头文件，不过还好网上的很多前辈们已经帮我们完成了这个工作，在本文的结束时会附上该文件。我觉得会最常用的几个函数如下（具体的参数可以看定义，上面应该写得比较清楚了）： &lt;p&gt;srv_rpcparams:获取参数的个数 &lt;p&gt;srv_paraminfo：获取指定参数的信息，数据的长度，类型，数据等 &lt;p&gt;srv_paramdata：获取image一类的值的指针 &lt;p&gt;srv_describe：创造返回值的描述 &lt;p&gt;srv_setcoldata：给返回的字段赋值 &lt;p&gt;srv_sendrow：返回一行数据 &lt;p&gt;srv_senddone：表示返回已经完成了。 &lt;p&gt;于是我们开始构建新的扩展存储过程： &lt;p&gt;function xp_Test(pSrvProc: SRV_PROC): Boolean; stdcall;//这个传时来的参数pSrvProc就是相当于是和sqlserver交互的上下文的指针了&lt;br&gt;var&lt;br&gt;&amp;nbsp; PType : Byte;&lt;br&gt;&amp;nbsp; cbMaxLen , ParaLen : DWORD;&lt;br&gt;&amp;nbsp; IsNULL : BOOL;  &lt;p&gt;&amp;nbsp; fs: TFileStream;&lt;br&gt;&amp;nbsp; p: Pointer;&lt;br&gt;&amp;nbsp; n: integer;&lt;br&gt;begin&lt;br&gt;&amp;nbsp; n := srv_rpcparams(pSrvProc);//先取一下有几个参数&lt;br&gt;&amp;nbsp; srv_paraminfo(pSrvProc, 1, @PType, @cbMaxLen, @ParaLen,&amp;nbsp; nil, @IsNULL);//取第一个参数的定义，注意参数的下标是从1开始的，而不是习惯上的0&lt;br&gt;&amp;nbsp; p := srv_paramdata(pSrvProc, 1);//由于我们要取image类型的，所以得用这个取数据的指针，否则就用下面这个，注意在这之前，p要先开好内存&lt;br&gt;&amp;nbsp; //srv_paraminfo(pSrvProc, 1, @PType, @cbMaxLen, @ParaLen,&amp;nbsp; @p, @IsNULL);&lt;br&gt;&amp;nbsp; fs := TFileStream.Create('d:\test.jpg', fmCreate);//由于无法debug只好能过文件把一些中间变量写到文件里，再用winhex来看了&lt;br&gt;&amp;nbsp; try&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fs.Write(n, SizeOf(Integer));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fs.Write(cbMaxLen, SizeOf(DWORD));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fs.Write(ParaLen, SizeOf(DWORD));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fs.Write(p^, ParaLen)&lt;br&gt;&amp;nbsp; finally&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FreeAndNil(fs);&lt;br&gt;&amp;nbsp; end;&lt;/p&gt; &lt;p&gt;//下面开始返回一行数据&lt;br&gt;&amp;nbsp; n := ParaLen;&lt;br&gt;&amp;nbsp; srv_describe(pSrvProc, 1 ,&amp;nbsp; 'Data', SRV_NULLTERM,&amp;nbsp; SRV_TDS_IMAGE,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; n, SRVBIGVARCHAR, n,&amp;nbsp; NIL);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_setcoldata(pSrvProc, 1 , p);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_sendrow(pSrvProc);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_senddone(pSrvProc, (SRV_DONE_COUNT or SRV_DONE_MORE), 0, 1);&lt;br&gt;end;&lt;/p&gt; &lt;p&gt;还是按hellowolrd的方法把它注册到SQLServer里面去。不过由于Image类型的字段不能在存储过程里设置临时变量，所以我们还有再麻烦一下：&lt;/p&gt; &lt;p&gt;Create PROCEDURE [dbo].[UXP_Test]&lt;br&gt;@in1 Image&lt;br&gt;AS&lt;br&gt;BEGIN&lt;br&gt; Insert into Test1(Data) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exec Master.dbo.xp_Test @in1&lt;br&gt;END&lt;br&gt;GO &lt;p&gt;这样来把我们处理过后的Image类型的字段插入到DB里面去。 &lt;p&gt;最后来看看那个Test.jpg的内容： &lt;p&gt;&lt;a href="http://webuc.net/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_SqlServerImage_FEF7_image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="32" alt="image" src="http://webuc.net/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_SqlServerImage_FEF7_image_thumb.png" width="244" border="0"&gt;&lt;/a&gt;  &lt;p&gt;Offset&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&amp;nbsp; 1&amp;nbsp; 2&amp;nbsp; 3&amp;nbsp; 4&amp;nbsp; 5&amp;nbsp; 6&amp;nbsp; 7&amp;nbsp;&amp;nbsp; 8&amp;nbsp; 9&amp;nbsp; A&amp;nbsp; B&amp;nbsp; C&amp;nbsp; D&amp;nbsp; E&amp;nbsp; F  &lt;p&gt;00000000&amp;nbsp;&amp;nbsp; 01 00 00 00 10 00 00 00&amp;nbsp; 72 03 00 00 47 49 46 38&amp;nbsp;&amp;nbsp; ........r...GIF8&lt;br&gt;00000010&amp;nbsp;&amp;nbsp; 39 61 A0 00 58 00 A2 00&amp;nbsp; 00 63 9C 9C FF 63 00 00&amp;nbsp;&amp;nbsp; 9a?X.?.c湝c..&lt;br&gt;00000020&amp;nbsp;&amp;nbsp; 9C 00 00 63 FF CE 31 31&amp;nbsp; FE 01 02 00 00 00 00 00&amp;nbsp;&amp;nbsp; ?.c?1?......&lt;br&gt;00000030&amp;nbsp;&amp;nbsp; 00 21 FF 0B 4E 45 54 53&amp;nbsp; 43 41 50 45 32 2E 30 03&amp;nbsp;&amp;nbsp; .!.NETSCAPE2.0. &lt;p&gt;点它一下看大图，就可以看到前四位是1，也就是传入了1个参数，接下来4位值是16（从这里也可以看出来那些image类型 的定义果真是16位这么长），再接下来4位这才是数据的真正长度，我是插入了一个GIF动画，所以它的长度和文件的长度是一样的：882，再后面就是文件的开始了GIF89a一个标准的GIF文件头 &lt;p&gt;看看这些数据插入到DB里是不是正确的呢？来看下图： &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://webuc.net/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_SqlServerImage_FEF7_image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="43" alt="image" src="http://webuc.net/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_SqlServerImage_FEF7_image_thumb_1.png" width="244" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;0x开头，说明它是以16进制数显示的，看开头的几位：474946383961和上面的16进制数对比一下可以看到，这里面的数据是正确的，也就是说我们的Image传入处理后，再返回来这一切都是成功的。&lt;/p&gt; &lt;p&gt;最后贴一下：MsOdsApi.pas(从下一行开始复制)&lt;/p&gt; &lt;p&gt;unit MsOdsApi;  &lt;p&gt;//------------------------------------------------------------&lt;br&gt;// Open Data Services header file: srv.h&lt;br&gt;// Copyright (c) 1989, 1990, 1991, 1997 by Microsoft Corp.&lt;br&gt;//  &lt;p&gt;// Avoid double inclusion&lt;br&gt;//#ifndef _ODS_SRV_H_&lt;br&gt;//&amp;nbsp; _ODS_SRV_H_  &lt;p&gt;//#include "windows.h"  &lt;p&gt;// ODS uses pack(4) on all CPU types&lt;br&gt;//#pragma pack(4)  &lt;p&gt;//#ifdef __cplusplus&lt;br&gt;//extern "C" {&lt;br&gt;//#endif  &lt;p&gt;// define model&lt;br&gt;//#if !defined( FAR )&lt;br&gt;//&amp;nbsp; FAR far&lt;br&gt;//#endif  &lt;p&gt;//------------------------------------------------------------&lt;br&gt;// Formats of data types&lt;br&gt;//#if !defined(DBTYPEDEFS) // Do not conflict with DBLIB definitions&lt;br&gt;//#if !defined(MAXNUMERICLEN) // Do not conflict with ODBC definitions  &lt;p&gt;//&amp;nbsp; DBTYPEDEFS  &lt;p&gt;interface  &lt;p&gt;uses&lt;br&gt;&amp;nbsp; Windows;  &lt;p&gt;type&lt;br&gt;&amp;nbsp; DBBOOL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Byte;&lt;br&gt;&amp;nbsp; DBBYTE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Byte;&lt;br&gt;&amp;nbsp; DBTINYINT&amp;nbsp;&amp;nbsp; = Byte;&lt;br&gt;&amp;nbsp; DBSMALLINT&amp;nbsp; = Smallint;&lt;br&gt;&amp;nbsp; DBUSMALLINT = Word;&lt;br&gt;&amp;nbsp; DBINT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Longint;&lt;br&gt;&amp;nbsp; DBCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Char;&lt;br&gt;&amp;nbsp; PDBCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = ^DBCHAR;&lt;br&gt;&amp;nbsp; DBBINARY&amp;nbsp;&amp;nbsp;&amp;nbsp; = Byte;&lt;br&gt;&amp;nbsp; DBBIT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Byte;&lt;br&gt;&amp;nbsp; DBFLT8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = Double;  &lt;p&gt;&amp;nbsp; srv_datetime = record&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Format for SRVDATETIME&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dtdays: Longint;&amp;nbsp; // number of days since 1/1/1900&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dttime: Longword; // number 300th second since mid&lt;br&gt;&amp;nbsp; end;&lt;br&gt;&amp;nbsp; DBDATETIME = srv_datetime;  &lt;p&gt;&amp;nbsp; srv_dbdatetime4 = record&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Format for SRVDATETIM4&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; numdays: Word; // number of days since 1/1/1900&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nummins: Word; // number of minutes sicne midnight&lt;br&gt;&amp;nbsp; end;&lt;br&gt;&amp;nbsp; DBDATETIM4 = srv_dbdatetime4;  &lt;p&gt;&amp;nbsp; srv_money = record&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Format for SRVMONEY&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mnyhigh: Longint;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mnylow : Longword;&lt;br&gt;&amp;nbsp; end;&lt;br&gt;&amp;nbsp; DBMONEY = srv_money;  &lt;p&gt;&amp;nbsp; DBFLT4&amp;nbsp;&amp;nbsp; = Double;&lt;br&gt;&amp;nbsp; DBMONEY4 = Longint;  &lt;p&gt;const&lt;br&gt;&amp;nbsp; MAXNUMERICDIG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 38;&lt;br&gt;&amp;nbsp; DEFAULTPRECISION&amp;nbsp; = 19; // 18&lt;br&gt;&amp;nbsp; DEFAULTSCALE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 0;&lt;br&gt;&amp;nbsp; MAXNUMERICLEN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 16;  &lt;p&gt;type&lt;br&gt;&amp;nbsp; srv_dbnumeric = packed record&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Format for SRVNUMERIC,SRVNUMERICN,SRVDECIMAL,SRVDECIMALN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; precision: Byte;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; scale&amp;nbsp;&amp;nbsp;&amp;nbsp; : Byte;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sign&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Byte;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 1 = Positive, 0 = Negative&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; val&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : array [0..MAXNUMERICLEN-1] of Byte; // Padded little-endian value&lt;br&gt;&amp;nbsp; end;&lt;br&gt;&amp;nbsp; DBNUMERIC = srv_dbnumeric;&lt;br&gt;&amp;nbsp; DBDECIMAL = DBNUMERIC;  &lt;p&gt;//#endif&amp;nbsp; // #if !defined(MAXNUMERICLEN)&lt;br&gt;//#endif&amp;nbsp; // #if !defined( DBTYPEDEFS )  &lt;p&gt;//------------------------------------------------------------&lt;br&gt;// Constants used by APIs  &lt;p&gt;// Type Tokens&lt;br&gt;const&lt;br&gt;&amp;nbsp; SRV_TDS_NULL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $1f;&lt;br&gt;&amp;nbsp; SRV_TDS_TEXT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $23;&lt;br&gt;&amp;nbsp; SRV_TDS_GUID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $24;&lt;br&gt;&amp;nbsp; SRV_TDS_VARBINARY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $25;&lt;br&gt;&amp;nbsp; SRV_TDS_INTN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $26;&lt;br&gt;&amp;nbsp; SRV_TDS_VARCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $27;&lt;br&gt;&amp;nbsp; SRV_TDS_BINARY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $2d;&lt;br&gt;&amp;nbsp; SRV_TDS_IMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $22;&lt;br&gt;&amp;nbsp; SRV_TDS_CHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $2f;&lt;br&gt;&amp;nbsp; SRV_TDS_INT1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $30;&lt;br&gt;&amp;nbsp; SRV_TDS_BIT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $32;&lt;br&gt;&amp;nbsp; SRV_TDS_INT2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $34;&lt;br&gt;&amp;nbsp; SRV_TDS_DECIMAL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $37;&lt;br&gt;&amp;nbsp; SRV_TDS_INT4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $38;&lt;br&gt;&amp;nbsp; SRV_TDS_DATETIM4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $3a;&lt;br&gt;&amp;nbsp; SRV_TDS_FLT4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $3b;&lt;br&gt;&amp;nbsp; SRV_TDS_MONEY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $3c;&lt;br&gt;&amp;nbsp; SRV_TDS_DATETIME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $3d;&lt;br&gt;&amp;nbsp; SRV_TDS_FLT8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $3e;&lt;br&gt;&amp;nbsp; SRV_TDS_NUMERIC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $3f;&lt;br&gt;&amp;nbsp; SRV_TDS_NTEXT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $63;&lt;br&gt;&amp;nbsp; SRV_TDS_BITN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $68;&lt;br&gt;&amp;nbsp; SRV_TDS_DECIMALN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $6a;&lt;br&gt;&amp;nbsp; SRV_TDS_NUMERICN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $6c;&lt;br&gt;&amp;nbsp; SRV_TDS_FLTN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $6d;&lt;br&gt;&amp;nbsp; SRV_TDS_MONEYN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $6e;&lt;br&gt;&amp;nbsp; SRV_TDS_DATETIMN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $6f;&lt;br&gt;&amp;nbsp; SRV_TDS_MONEY4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $7a;&lt;br&gt;&amp;nbsp; SRV_TDS_INT8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $7f;&amp;nbsp; // SQL 2000 and later&lt;br&gt;&amp;nbsp; SRV_TDS_BIGVARBINARY&amp;nbsp;&amp;nbsp; = $A5;&lt;br&gt;&amp;nbsp; SRV_TDS_BIGVARCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $A7;&lt;br&gt;&amp;nbsp; SRV_TDS_BIGBINARY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $AD;&lt;br&gt;&amp;nbsp; SRV_TDS_BIGCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $AF;&lt;br&gt;&amp;nbsp; SRV_TDS_NVARCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $e7;&lt;br&gt;&amp;nbsp; SRV_TDS_NCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $ef;  &lt;p&gt;// Datatypes&lt;br&gt;// Also: values of symbol parameter to srv_symbol when type = SRV_DATATYPE&lt;br&gt;&amp;nbsp; SRVNULL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_NULL;&lt;br&gt;&amp;nbsp; SRVTEXT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_TEXT;&lt;br&gt;&amp;nbsp; SRVGUID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_GUID;&lt;br&gt;&amp;nbsp; SRVVARBINARY&amp;nbsp;&amp;nbsp; = SRV_TDS_VARBINARY;&lt;br&gt;&amp;nbsp; SRVINTN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_INTN;&lt;br&gt;&amp;nbsp; SRVVARCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_VARCHAR;&lt;br&gt;&amp;nbsp; SRVBINARY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_BINARY;&lt;br&gt;&amp;nbsp; SRVIMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_IMAGE;&lt;br&gt;&amp;nbsp; SRVCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_CHAR;&lt;br&gt;&amp;nbsp; SRVINT1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_INT1;&lt;br&gt;&amp;nbsp; SRVBIT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_BIT;&lt;br&gt;&amp;nbsp; SRVINT2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_INT2;&lt;br&gt;&amp;nbsp; SRVDECIMAL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_DECIMAL;&lt;br&gt;&amp;nbsp; SRVINT4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_INT4;&lt;br&gt;&amp;nbsp; SRVDATETIM4&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_DATETIM4;&lt;br&gt;&amp;nbsp; SRVFLT4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_FLT4;&lt;br&gt;&amp;nbsp; SRVMONEY&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_MONEY;&lt;br&gt;&amp;nbsp; SRVDATETIME&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_DATETIME;&lt;br&gt;&amp;nbsp; SRVFLT8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_FLT8;&lt;br&gt;&amp;nbsp; SRVNUMERIC&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_NUMERIC;&lt;br&gt;&amp;nbsp; SRVNTEXT&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_NTEXT;&lt;br&gt;&amp;nbsp; SRVBITN&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_BITN;&lt;br&gt;&amp;nbsp; SRVDECIMALN&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_DECIMALN;&lt;br&gt;&amp;nbsp; SRVNUMERICN&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_NUMERICN;&lt;br&gt;&amp;nbsp; SRVFLTN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_FLTN;&lt;br&gt;&amp;nbsp; SRVMONEYN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_MONEYN;&lt;br&gt;&amp;nbsp; SRVDATETIMN&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_DATETIMN;&lt;br&gt;&amp;nbsp; SRVMONEY4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_MONEY4;&lt;br&gt;&amp;nbsp; SRVINT8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_INT8;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // SQL 2000 and later&lt;br&gt;&amp;nbsp; SRVBIGVARBINARY = SRV_TDS_BIGVARBINARY;&lt;br&gt;&amp;nbsp; SRVBIGVARCHAR&amp;nbsp; = SRV_TDS_BIGVARCHAR;&lt;br&gt;&amp;nbsp; SRVBIGBINARY&amp;nbsp;&amp;nbsp; = SRV_TDS_BIGBINARY;&lt;br&gt;&amp;nbsp; SRVBIGCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_BIGCHAR;&lt;br&gt;&amp;nbsp; SRVNVARCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_NVARCHAR;&lt;br&gt;&amp;nbsp; SRVNCHAR&amp;nbsp;&amp;nbsp;&amp;nbsp; = SRV_TDS_NCHAR;  &lt;p&gt;// values for srv_symbol type parameter&lt;br&gt; SRV_ERROR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 0;&lt;br&gt; SRV_DONE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 1;&lt;br&gt; SRV_DATATYPE&amp;nbsp; = 2;&lt;br&gt; SRV_EVENT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 4;  &lt;p&gt;// values for srv_symbol symbol parameter, when type = SRV_ERROR&lt;br&gt;&amp;nbsp; SRV_ENO_OS_ERR&amp;nbsp;&amp;nbsp;&amp;nbsp; = 0;&lt;br&gt;&amp;nbsp; SRV_INFO&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 1;&lt;br&gt;&amp;nbsp; SRV_FATAL_PROCESS = 10;&lt;br&gt;&amp;nbsp; SRV_FATAL_SERVER&amp;nbsp; = 19;  &lt;p&gt;// Types of server events&lt;br&gt;// Also: values for srv_symbol symbol parameter, when type = SRV_EVENT&lt;br&gt;&amp;nbsp; SRV_CONTINUE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 0;&lt;br&gt;&amp;nbsp; SRV_LANGUAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 1;&lt;br&gt;&amp;nbsp; SRV_CONNECT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 2;&lt;br&gt;&amp;nbsp; SRV_RPC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 3;&lt;br&gt;&amp;nbsp; SRV_RESTART&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 4;&lt;br&gt;&amp;nbsp; SRV_DISCONNECT&amp;nbsp;&amp;nbsp;&amp;nbsp; = 5;&lt;br&gt;&amp;nbsp; SRV_ATTENTION&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 6;&lt;br&gt;&amp;nbsp; SRV_SLEEP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 7;&lt;br&gt;&amp;nbsp; SRV_START&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 8;&lt;br&gt;&amp;nbsp; SRV_STOP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 9;&lt;br&gt;&amp;nbsp; SRV_EXIT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 10;&lt;br&gt;&amp;nbsp; SRV_CANCEL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 11;&lt;br&gt;&amp;nbsp; SRV_SETUP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 12;&lt;br&gt;&amp;nbsp; SRV_CLOSE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 13;&lt;br&gt;&amp;nbsp; SRV_PRACK&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 14;&lt;br&gt;&amp;nbsp; SRV_PRERROR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 15;&lt;br&gt;&amp;nbsp; SRV_ATTENTION_ACK = 16;&lt;br&gt;&amp;nbsp; SRV_CONNECT_V7&amp;nbsp;&amp;nbsp;&amp;nbsp; = 16; // TDS type for TDS 7 clients.&amp;nbsp; Overloaded with SRV_ATTENTION_ACK&lt;br&gt;&amp;nbsp; SRV_SKIP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 17;&lt;br&gt;&amp;nbsp; SRV_TRANSMGR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 18;&lt;br&gt;&amp;nbsp; SRV_OLEDB&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 20;&lt;br&gt;&amp;nbsp; SRV_INTERNAL_HANDLER&amp;nbsp;&amp;nbsp;&amp;nbsp; = 99;&lt;br&gt;&amp;nbsp; SRV_PROGRAMMER_DEFINED&amp;nbsp; = 100;  &lt;p&gt;// values for srv_config option parameter&lt;br&gt;&amp;nbsp; SRV_CONNECTIONS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 1;&lt;br&gt;&amp;nbsp; SRV_LOGFILE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 2;&lt;br&gt;&amp;nbsp; SRV_STACKSIZE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 3;&lt;br&gt;&amp;nbsp; SRV_REMOTE_ACCESS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 7;&lt;br&gt;&amp;nbsp; SRV_REMOTE_CONNECTIONS = 9;&lt;br&gt;&amp;nbsp; SRV_MAX_PACKETS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 10;&lt;br&gt;&amp;nbsp; SRV_MAXWORKINGTHREADS&amp;nbsp; = 11;&lt;br&gt;&amp;nbsp; SRV_MINWORKINGTHREADS&amp;nbsp; = 12;&lt;br&gt;&amp;nbsp; SRV_THREADTIMEOUT&amp;nbsp;&amp;nbsp;&amp;nbsp; = 13;&lt;br&gt;&amp;nbsp; SRV_MAX_PACKETSIZE&amp;nbsp;&amp;nbsp;&amp;nbsp; = 17;&lt;br&gt;&amp;nbsp; SRV_THREADPRIORITY&amp;nbsp;&amp;nbsp;&amp;nbsp; = 18;&lt;br&gt;&amp;nbsp; SRV_ANSI_CODEPAGE&amp;nbsp;&amp;nbsp;&amp;nbsp; = 19;&lt;br&gt;&amp;nbsp; SRV_DEFAULT_PACKETSIZE = 26;&lt;br&gt;&amp;nbsp; SRV_PASSTHROUGH&amp;nbsp;&amp;nbsp;&amp;nbsp; = 27;  &lt;p&gt;// vlaues for srv_config value parameter when option = SRV_THREADPRIORITY&lt;br&gt;&amp;nbsp; SRV_PRIORITY_LOW&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = THREAD_PRIORITY_LOWEST;&lt;br&gt;&amp;nbsp; SRV_PRIORITY_NORMAL&amp;nbsp;&amp;nbsp; = THREAD_PRIORITY_NORMAL;&lt;br&gt;&amp;nbsp; SRV_PRIORITY_HIGH&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = THREAD_PRIORITY_HIGHEST;&lt;br&gt;&amp;nbsp; SRV_PRIORITY_CRITICAL = THREAD_PRIORITY_TIME_CRITICAL;  &lt;p&gt;// values for srv_sfield field parameter&lt;br&gt;&amp;nbsp; SRV_SERVERNAME = 0;&lt;br&gt;&amp;nbsp; SRV_VERSION&amp;nbsp;&amp;nbsp;&amp;nbsp; = 6;  &lt;p&gt;// Length to indicate string is null terminated&lt;br&gt;&amp;nbsp; SRV_NULLTERM&amp;nbsp;&amp;nbsp; = -1;  &lt;p&gt;// values of msgtype parameter to srv_sendmsg&lt;br&gt;&amp;nbsp; SRV_MSG_INFO&amp;nbsp;&amp;nbsp; = 1;&lt;br&gt;&amp;nbsp; SRV_MSG_ERROR&amp;nbsp; = 2;  &lt;p&gt;// values of status parameter to srv_senddone&lt;br&gt;// Also: values for symbol parameters to srv_symbol when type = SRV_DONE&lt;br&gt;&amp;nbsp; SRV_DONE_FINAL&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0000;&lt;br&gt;&amp;nbsp; SRV_DONE_MORE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0001;&lt;br&gt;&amp;nbsp; SRV_DONE_ERROR&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0002;&lt;br&gt;&amp;nbsp; SRV_DONE_COUNT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0010;&lt;br&gt;&amp;nbsp; SRV_DONE_RPC_IN_BATCH&amp;nbsp;&amp;nbsp; = $0080;  &lt;p&gt;// return values of srv_paramstatus&lt;br&gt;&amp;nbsp; SRV_PARAMRETURN&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0001;&lt;br&gt;&amp;nbsp; SRV_PARAMDEFAULT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0002;  &lt;p&gt;// return values of srv_rpcoptions&lt;br&gt;&amp;nbsp; SRV_RECOMPILE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0001;&lt;br&gt;&amp;nbsp; SRV_NOMETADATA&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $0002;  &lt;p&gt;// values of field parameter to srv_pfield&lt;br&gt;//&amp;nbsp; SRV_LANGUAGE 1&amp;nbsp;&amp;nbsp; already defined above&lt;br&gt;//&amp;nbsp; SRV_EVENT&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp; already defined above&lt;br&gt;&amp;nbsp; SRV_SPID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 10;&lt;br&gt;&amp;nbsp; SRV_NETSPID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 11;&lt;br&gt;&amp;nbsp; SRV_TYPE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 12;&lt;br&gt;&amp;nbsp; SRV_STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 13;&lt;br&gt;&amp;nbsp; SRV_RMTSERVER&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 14;&lt;br&gt;&amp;nbsp; SRV_HOST&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 15;&lt;br&gt;&amp;nbsp; SRV_USER&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 16;&lt;br&gt;&amp;nbsp; SRV_PWD&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 17;&lt;br&gt;&amp;nbsp; SRV_CPID&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 18;&lt;br&gt;&amp;nbsp; SRV_APPLNAME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 19;&lt;br&gt;&amp;nbsp; SRV_TDS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 20;&lt;br&gt;&amp;nbsp; SRV_CLIB&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 21;&lt;br&gt;&amp;nbsp; SRV_LIBVERS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 22;&lt;br&gt;&amp;nbsp; SRV_ROWSENT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 23;&lt;br&gt;&amp;nbsp; SRV_BCPFLAG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 24;&lt;br&gt;&amp;nbsp; SRV_NATLANG&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 25;&lt;br&gt;&amp;nbsp; SRV_PIPEHANDLE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 26;&lt;br&gt;&amp;nbsp; SRV_NETWORK_MODULE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 27;&lt;br&gt;&amp;nbsp; SRV_NETWORK_VERSION&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 28;&lt;br&gt;&amp;nbsp; SRV_NETWORK_CONNECTION&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 29;&lt;br&gt;&amp;nbsp; SRV_LSECURE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 30;&lt;br&gt;&amp;nbsp; SRV_SAXP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 31;&lt;br&gt;&amp;nbsp; SRV_UNICODE_USER&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 33;&lt;br&gt;&amp;nbsp; SRV_UNICODE_PWD&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 35;&lt;br&gt;&amp;nbsp; SRV_SPROC_CODEPAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 36;  &lt;p&gt;// return value of SRV_TDSVERSION macro&lt;br&gt;&amp;nbsp; SRV_TDS_NONE&amp;nbsp; = 0;&lt;br&gt;&amp;nbsp; SRV_TDS_2_0&amp;nbsp;&amp;nbsp; = 1;&lt;br&gt;&amp;nbsp; SRV_TDS_3_4&amp;nbsp;&amp;nbsp; = 2;&lt;br&gt;&amp;nbsp; SRV_TDS_4_2&amp;nbsp;&amp;nbsp; = 3;&lt;br&gt;&amp;nbsp; SRV_TDS_6_0&amp;nbsp;&amp;nbsp; = 4;&lt;br&gt;&amp;nbsp; SRV_TDS_7_0&amp;nbsp;&amp;nbsp; = 5;  &lt;p&gt;// Return values from APIs&lt;br&gt;type&lt;br&gt; SRVRETCODE = Integer;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // SUCCEED or FAIL&lt;br&gt; RETCODE&amp;nbsp;&amp;nbsp;&amp;nbsp; = Integer;  &lt;p&gt;const&lt;br&gt;&amp;nbsp; SUCCEED = 1;&amp;nbsp;&amp;nbsp; // Successful return value&lt;br&gt;&amp;nbsp; FAIL&amp;nbsp;&amp;nbsp;&amp;nbsp; = 0;&amp;nbsp;&amp;nbsp; // Unsuccessful return value  &lt;p&gt;&amp;nbsp; SRV_DUPLICATE_HANDLER&amp;nbsp;&amp;nbsp; = 2;&amp;nbsp;&amp;nbsp; // additional return value for srv_pre/post_handle  &lt;p&gt;//------------------------------------------------&lt;br&gt;//PreDeclare structures&lt;br&gt;//&lt;br&gt;{struct srv_server;&lt;br&gt;typedef struct srv_server SRV_SERVER;  &lt;p&gt;struct srv_config;&lt;br&gt;typedef struct srv_config SRV_CONFIG;  &lt;p&gt;struct srv_proc;&lt;br&gt;typedef struct srv_proc SRV_PROC;}&lt;br&gt;type&lt;br&gt;&amp;nbsp; SRV_SERVER = Pointer;&lt;br&gt;&amp;nbsp; SRV_CONFIG = Pointer;&lt;br&gt;&amp;nbsp; SRV_PROC&amp;nbsp;&amp;nbsp; = Pointer;  &lt;p&gt;//------------------------------------------------&lt;br&gt;//------------------------------------------------&lt;br&gt;// ODS MACROs &amp;amp; APIs  &lt;p&gt;// Describing and sending a result set&lt;br&gt;function srv_describe(srvproc: SRV_PROC;&lt;br&gt;&amp;nbsp; colnumber: Integer; column_name: PCHAR; namelen: Integer;&lt;br&gt;&amp;nbsp; desttype, destlen, srctype, srclen: Integer; srcData: Pointer&lt;br&gt;): Integer; cdecl;  &lt;p&gt;function srv_setutype(srvproc: SRV_PROC; column: Integer; usertype: Longint): Integer; cdecl;&lt;br&gt;function srv_setcoldata(srvproc: SRV_PROC; column: Integer; data: Pointer): Integer; cdecl;&lt;br&gt;function srv_setcollen(srvproc: SRV_PROC; column, len: Integer): Integer; cdecl;&lt;br&gt;function srv_sendrow(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_senddone(srvproc: SRV_PROC; status, curcmd: Word; count: Longint): Integer; cdecl;  &lt;p&gt;// Dealing with Extended Procedure parameters&lt;br&gt;function srv_rpcparams(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_paraminfo(srvproc: SRV_PROC; n: Integer; pbType: PByte; &lt;br&gt;&amp;nbsp; pcbMaxLen, pcbActualLen: PULONG; pbData: PByte; pfNull: PBOOL): Integer; cdecl;&lt;br&gt;function srv_paramsetoutput(srvproc: SRV_PROC;&lt;br&gt;&amp;nbsp; n: Integer; pbData: PByte; cbLen: ULONG; fNull: BOOL): Integer; cdecl;  &lt;p&gt;function srv_paramdata(srvproc: SRV_PROC; n: Integer): Pointer; cdecl;&lt;br&gt;function srv_paramlen(srvproc: SRV_PROC; n: Integer): Integer; cdecl;&lt;br&gt;function srv_parammaxlen(srvproc: SRV_PROC; n: Integer): Integer; cdecl;&lt;br&gt;function srv_paramtype(srvproc: SRV_PROC; n: Integer): Integer; cdecl;&lt;br&gt;function srv_paramset(srvproc: SRV_PROC; n: Integer; data: Pointer; int: Integer): Integer; cdecl;  &lt;p&gt;function srv_paramname(srvproc: SRV_PROC; n: Integer; var len: Integer): PChar; cdecl;&lt;br&gt;function srv_paramnumber(srvproc: SRV_PROC; name: PChar; namelen: Integer): Integer; cdecl;  &lt;p&gt;//--------------------------------------------------------------&lt;br&gt;//--------------------------------------------------------------&lt;br&gt;// The rest of these APIs are still supported, in SQL Server 7.0,&lt;br&gt;// but may not be supported after SQL Server 7.0  &lt;p&gt;// MACROs&lt;br&gt;{&amp;nbsp; SRV_GETCONFIG(a)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_getconfig&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ( a )&lt;br&gt;&amp;nbsp; SRV_GETSERVER(a)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_getserver&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ( a )&lt;br&gt;&amp;nbsp; SRV_GOT_ATTENTION(a)&amp;nbsp;&amp;nbsp; srv_got_attention ( a )&lt;br&gt;SRV_EVENTDATA(a)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_eventdata&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ( a )&lt;br&gt;SRV_IODEAD(a)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_iodead&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ( a )&lt;br&gt;SRV_TDSVERSION(a)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv_tdsversion&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ( a )}  &lt;p&gt;function srv_getconfig(server: SRV_SERVER): SRV_CONFIG; cdecl;&lt;br&gt;function srv_getserver(srvproc: SRV_PROC): SRV_SERVER; cdecl;&lt;br&gt;function srv_got_attention(srvproc: SRV_PROC): Bool; cdecl;&lt;br&gt;function srv_eventdata(srvproc: SRV_PROC): Pointer; cdecl;  &lt;p&gt;// Memory&lt;br&gt;function srv_alloc(ulSize: Longint): Pointer; cdecl;&lt;br&gt;function srv_bmove(from: Pointer; pto: Pointer; count: Longint): Integer; cdecl;&lt;br&gt;function srv_bzero(location: Pointer; count: Longint): Integer; cdecl;&lt;br&gt;function srv_free(ptr: Pointer): Integer; cdecl;  &lt;p&gt;function srv_config_fn(config: SRV_CONFIG; option: Longint; value: PChar; valuelen: Integer): Integer; cdecl;&lt;br&gt;function srv_config_alloc: SRV_CONFIG; cdecl;&lt;br&gt;function srv_convert(srvproc: SRV_PROC; srctype: Integer; src: Pointer; srclen: DBINT;&lt;br&gt;&amp;nbsp; desttype: Integer; dest: Pointer; destlen: DBINT): Integer; cdecl;&lt;br&gt;{&lt;br&gt;int (*&amp;nbsp; srv_errhandle(int (* handler)(SRV_SERVER * server,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SRV_PROC&amp;nbsp;&amp;nbsp; * srvproc,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srverror,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; severity,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; state,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oserrnum,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * errtext,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; errtextlen,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * oserrtext,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oserrtextlen)))&lt;br&gt;&amp;nbsp;&amp;nbsp; ( SRV_SERVER * server,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SRV_PROC&amp;nbsp;&amp;nbsp; * srvproc,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srverror,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; severity,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BYTE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; state,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oserrnum,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * errtext,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; errtextlen,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; char&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * oserrtext,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oserrtextlen );&lt;br&gt;}&lt;br&gt;function srv_event_fn(srvproc: SRV_PROC; event: Integer; data: PByte): Integer; cdecl;&lt;br&gt;function srv_getuserdata(srvproc: SRV_PROC): Pointer; cdecl;&lt;br&gt;function srv_getbindtoken(srvproc: SRV_PROC; token_buf: PChar): Integer; cdecl;&lt;br&gt;function srv_getdtcxact(srvproc: SRV_PROC; ppv: Pointer): Integer; cdecl;  &lt;p&gt;//typedef int (* EventHandler)(void*);&lt;br&gt;type&lt;br&gt;&amp;nbsp; EventHandler = Pointer;&lt;br&gt;function srv_handle(server: SRV_SERVER; int: Longint; handler: EventHandler): EventHandler; cdecl;  &lt;p&gt;function srv_impersonate_client(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_init(config: SRV_CONFIG; connectname: PChar; namelen: Integer): SRV_SERVER; cdecl;&lt;br&gt;function srv_iodead(srvproc: SRV_PROC): Bool; cdecl;  &lt;p&gt;function srv_langcpy(srvproc: SRV_PROC; start, nbytes: Longint; buffer: PChar): Longint; cdecl;&lt;br&gt;function srv_langlen(srvproc: SRV_PROC): Longint; cdecl;&lt;br&gt;function srv_langptr(srvproc: SRV_PROC): Pointer; cdecl;  &lt;p&gt;function srv_log(server: SRV_SERVER; datestamp: Bool; msg: PChar; msglen: Integer): Integer; cdecl;&lt;br&gt;function srv_paramstatus(srvproc: SRV_PROC; n: Integer): Integer; cdecl;&lt;br&gt;function srv_pfield(srvproc: SRV_PROC; field: Integer; len: PInteger): PChar; cdecl;  &lt;p&gt;function srv_returnval(srvproc: SRV_PROC; value_name: PDBCHAR; len: Integer; status: Byte;&lt;br&gt;&amp;nbsp; iType, maxlen, datalen: DBINT; value: PByte): Integer; cdecl;  &lt;p&gt;function srv_revert_to_self(srvproc: SRV_PROC): Integer; cdecl;  &lt;p&gt;function srv_rpcdb(srvproc: SRV_PROC; len: PInteger): PChar; cdecl;&lt;br&gt;function srv_rpcname(srvproc: SRV_PROC; len: PInteger): PChar; cdecl;&lt;br&gt;function srv_rpcnumber(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_rpcoptions(srvproc: SRV_PROC): Word; cdecl;&lt;br&gt;function srv_rpcowner(srvproc: SRV_PROC; len: PInteger): PChar; cdecl;  &lt;p&gt;function srv_run(server: SRV_SERVER): Integer; cdecl;  &lt;p&gt;function srv_sendmsg(srvproc: SRV_PROC;&lt;br&gt;&amp;nbsp; msgtype: Integer; msgnum: DBINT; msgClass, state: DBTINYINT;&lt;br&gt;&amp;nbsp; rpcname: PChar; rpcnamelen: Integer;&lt;br&gt;&amp;nbsp; linenum: Word; msg: PChar; msglen: Integer): Integer; cdecl;  &lt;p&gt;function srv_ansi_sendmsg(srvproc: SRV_PROC;&lt;br&gt;&amp;nbsp; msgtype: Integer; msgnum: DBINT; msgClass, state: DBTINYINT;&lt;br&gt;&amp;nbsp; rpcname: PChar; rpcnamelen: Integer;&lt;br&gt;&amp;nbsp; linenum: Word; msg: PChar; msglen: Integer): Integer; cdecl;  &lt;p&gt;function srv_sendstatus(srvproc: SRV_PROC; status: Longint): Integer; cdecl;&lt;br&gt;function srv_setuserdata(srvproc: SRV_PROC; ptr: Pointer): Integer; cdecl;&lt;br&gt;function srv_sfield(server: SRV_SERVER; field: Integer; len: PInteger): PChar; cdecl;&lt;br&gt;function srv_symbol(iType, symbol: Integer; len: PInteger): PChar; cdecl;&lt;br&gt;function srv_tdsversion(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_writebuf(srvproc: SRV_PROC; ptr: Pointer; count: Word): Integer; cdecl;&lt;br&gt;function srv_willconvert(srctype, desttype: Integer): Bool; cdecl;&lt;br&gt;procedure srv_ackattention(srvproc: SRV_PROC); cdecl;&lt;br&gt;function srv_terminatethread(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_sendstatistics(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_clearstatistics(srvproc: SRV_PROC): Integer; cdecl;&lt;br&gt;function srv_setevent(server: SRV_SERVER; event: Integer): Integer; cdecl;&lt;br&gt;function srv_message_handler(srvproc: SRV_PROC;&lt;br&gt;&amp;nbsp; errornum: Integer; severity, state: Byte; oserrnum: Integer; errtext: PChar;&lt;br&gt;&amp;nbsp; errtextlen: Integer; oserrtext: PChar; oserrtextlen: Integer): Integer; cdecl;  &lt;p&gt;function srv_pre_handle(server: SRV_SERVER; srvproc: SRV_PROC;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; event: Longint; handler: EventHandler;&amp;nbsp; remove: Bool): Integer; cdecl;&lt;br&gt;function srv_post_handle(server: SRV_SERVER; srvproc: SRV_PROC;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; event: Longint; handler: EventHandler;&amp;nbsp; remove: Bool): Integer; cdecl;  &lt;p&gt;function srv_post_completion_queue(srvproc: SRV_PROC; inbuf: PChar; inbuflen: PChar): Integer; cdecl;&lt;br&gt;function srv_IgnoreAnsiToOem(srvproc: SRV_PROC; bTF: BOOL): Integer; cdecl;  &lt;p&gt;//#ifdef __cplusplus&lt;br&gt;//}&lt;br&gt;//#endif  &lt;p&gt;//#pragma pack()  &lt;p&gt;const&lt;br&gt;&amp;nbsp; SS_MAJOR_VERSION&amp;nbsp;&amp;nbsp; = 7;&lt;br&gt;&amp;nbsp; SS_MINOR_VERSION&amp;nbsp;&amp;nbsp; = 00;&lt;br&gt;&amp;nbsp; SS_LEVEL_VERSION&amp;nbsp;&amp;nbsp; = 0000;&lt;br&gt;&amp;nbsp; SS_MINIMUM_VERSION = '7.00.00.0000';&lt;br&gt;&amp;nbsp; ODS_VERSION&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = ((SS_MAJOR_VERSION shl 24) or (SS_MINOR_VERSION shl 16));  &lt;p&gt;//#endif //_ODS_SRV_H_  &lt;p&gt;//////////////////////////////////////////////////////////////////&lt;br&gt;// Suggested implementation of __GetXpVersion&lt;br&gt;//&lt;br&gt;//__declspec(dllexport) ULONG __GetXpVersion()&lt;br&gt;//&amp;nbsp;&amp;nbsp; {&lt;br&gt;//&amp;nbsp;&amp;nbsp; return ODS_VERSION;&lt;br&gt;//&amp;nbsp;&amp;nbsp; }&lt;br&gt;//////////////////////////////////////////////////////////////////  &lt;p&gt;implementation  &lt;p&gt;const&lt;br&gt;&amp;nbsp; sLibName = 'Opends60.DLL';  &lt;p&gt;function srv_describe;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_describe';&lt;br&gt;function srv_setutype;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_setutype';&lt;br&gt;function srv_setcoldata;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_setcoldata';&lt;br&gt;function srv_setcollen;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_setcollen';&lt;br&gt;function srv_sendrow;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_sendrow';&lt;br&gt;function srv_senddone;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_senddone';  &lt;p&gt;// Dealing with Extended Procedure parameters&lt;br&gt;function srv_rpcparams;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_rpcparams';&lt;br&gt;function srv_paraminfo;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paraminfo';&lt;br&gt;function srv_paramsetoutput;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramsetoutput';  &lt;p&gt;function srv_paramdata;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramdata';&lt;br&gt;function srv_paramlen;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramlen';&lt;br&gt;function srv_parammaxlen;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_parammaxlen';&lt;br&gt;function srv_paramtype;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramtype';&lt;br&gt;function srv_paramset;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramset';  &lt;p&gt;function srv_paramname;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramname';&lt;br&gt;function srv_paramnumber;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramnumber';  &lt;p&gt;//--------------------------------------------------------------&lt;br&gt;// The rest of these APIs are still supported, in SQL Server 7.0,&lt;br&gt;// but may not be supported after SQL Server 7.0  &lt;p&gt;function srv_getconfig;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_getconfig';&lt;br&gt;function srv_getserver;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_getserver';&lt;br&gt;function srv_got_attention;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_got_attention';&lt;br&gt;function srv_eventdata;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_eventdata';  &lt;p&gt;// Memory&lt;br&gt;function srv_alloc;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_alloc';&lt;br&gt;function srv_bmove;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_bmove';&lt;br&gt;function srv_bzero;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_bzero';&lt;br&gt;function srv_free;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_free';  &lt;p&gt;function srv_config_fn;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_config';&lt;br&gt;function srv_config_alloc;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_config_alloc';&lt;br&gt;function srv_convert;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_convert';&lt;br&gt;function srv_event_fn;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_event';&lt;br&gt;function srv_getuserdata;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_getuserdata';&lt;br&gt;function srv_getbindtoken;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_getbindtoken';&lt;br&gt;function srv_getdtcxact;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_getdtcxact';&lt;br&gt;function srv_handle;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_handle';&lt;br&gt;function srv_impersonate_client;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_impersonate_client';&lt;br&gt;function srv_init;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_init';&lt;br&gt;function srv_iodead;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_iodead';&lt;br&gt;function srv_langcpy;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_langcpy';&lt;br&gt;function srv_langlen;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_langlen';&lt;br&gt;function srv_langptr;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_langptr';&lt;br&gt;function srv_log;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_log';&lt;br&gt;function srv_paramstatus;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_paramstatus';&lt;br&gt;function srv_pfield;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_pfield';&lt;br&gt;function srv_returnval;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_returnval';&lt;br&gt;function srv_revert_to_self;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_revert_to_self';  &lt;p&gt;function srv_rpcdb;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_rpcdb';&lt;br&gt;function srv_rpcname;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_rpcname';&lt;br&gt;function srv_rpcnumber;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_rpcnumber';&lt;br&gt;function srv_rpcoptions;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_rpcoptions';&lt;br&gt;function srv_rpcowner;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_rpcowner';  &lt;p&gt;function srv_run;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_run';  &lt;p&gt;function srv_sendmsg;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_sendmsg';&lt;br&gt;function srv_ansi_sendmsg;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_ansi_sendmsg';  &lt;p&gt;function srv_sendstatus;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_sendstatus';&lt;br&gt;function srv_setuserdata;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_setuserdata';&lt;br&gt;function srv_sfield;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_sfield';&lt;br&gt;function srv_symbol;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_symbol';&lt;br&gt;function srv_tdsversion;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_tdsversion';&lt;br&gt;function srv_writebuf;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_writebuf';&lt;br&gt;function srv_willconvert;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_willconvert';&lt;br&gt;procedure srv_ackattention;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_ackattention';&lt;br&gt;function srv_terminatethread;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_terminatethread';&lt;br&gt;function srv_sendstatistics;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_sendstatistics';&lt;br&gt;function srv_clearstatistics;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_clearstatistics';&lt;br&gt;function srv_setevent;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_setevent';&lt;br&gt;function srv_message_handler;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_message_handler';  &lt;p&gt;function srv_pre_handle;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_pre_handle';&lt;br&gt;function srv_post_handle;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_post_handle';&lt;br&gt;function srv_post_completion_queue;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_post_completion_queue';&lt;br&gt;function srv_IgnoreAnsiToOem;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; external sLibName name 'srv_IgnoreAnsiToOem';  &lt;p&gt;end.&lt;/p&gt;&lt;/blockquote&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/10105.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>AVI文件格式研究中碰到的一些问题的解决办法</title><link>http://webuc.net/chinahuman/archive/2008/08/25/10099.aspx</link><pubDate>Mon, 25 Aug 2008 14:54:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2008/08/25/10099.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/10099.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2008/08/25/10099.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/10099.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/10099.aspx</trackback:ping><description>&lt;P&gt;最近在研究AVI文件格式的生成问题，碰到以下的问题，找到解决办法，共享如下：&lt;/P&gt;
&lt;P&gt;1.生成的文件格式的校验问题：&lt;/P&gt;
&lt;P&gt;因为是根据AVI RIFF File Refence这个文档来生成的，所以对错不知道。因此需要一个校验工具。偶觉得有两个工具不错：&lt;/P&gt;
&lt;P&gt;a. Gsport这个是暴风影音一类的工具会带的工具。如果格式有错误，它会提示出来。&lt;/P&gt;
&lt;P&gt;&lt;A href="http://webuc.net/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_AVI_D15F_image_4.png"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=244 alt=image src="/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_AVI_D15F_image_thumb_1.png" width=243 border=0&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;b.VirtualDub 在这里面点工具菜单里面有十六进制编辑器，按Ctrl+R可以显示出RIFF的树，这样比较容易找出问题来。&lt;/P&gt;
&lt;P&gt;&lt;A href="http://webuc.net/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_AVI_D15F_image_2.png"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=244 alt=image src="/images/webuc_net/chinahuman/484/o_WindowsLiveWriter_AVI_D15F_image_thumb.png" width=229 border=0&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;2.一切都是按文档的说明来生成的，用播放器来播放是正常的，但是用如上的校验工具来看，里面有错位。在trunck列表里面，发现只有第一个是识别出来，后面的跳了一位无法识别。&lt;/P&gt;
&lt;P&gt;经研究发现是存在着奇偶对齐的问题，如果内容是奇数位，那么得在后面补上一位来对齐，但是这一位不能记在这个trunck的长度里面，否则解码器多读了一位可能会引起解码错误。&lt;/P&gt;
&lt;P&gt;计划把音频加入，以及功能完善化后，发布DLL供人调用。&lt;/P&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/10099.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>DELPHI调试WINDOWS服务的一点心得</title><link>http://webuc.net/chinahuman/archive/2008/06/14/10007.aspx</link><pubDate>Sat, 14 Jun 2008 04:30:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2008/06/14/10007.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/10007.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2008/06/14/10007.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/10007.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/10007.aspx</trackback:ping><description>&lt;p&gt;Delphi可以很轻松地开发windows服务，可是调试的时候，确有问题。服务能跑起来，可以把把调试器附加到服务的进程上。如果服务起不来呢？该如何调试呢？&lt;/p&gt; &lt;p&gt;如果直接按F9，则服务只是被创建，还没有起动，就会自已退出去了。&lt;/p&gt; &lt;p&gt;我想到的办法就是让服务以普通程序的方式来运行。&lt;/p&gt; &lt;p&gt;为了使用同一份代码，所以我彩用条件编译的方式来实现，在工程的DPR文件里面加上条件：&lt;/p&gt; &lt;p&gt;DELPHI的VCL可以说是一个很精妙的设计。对于一个普通程序来说，它初始化出来的Application是TApplication,而服务的Application是TServiceApplication，所以在想让服务以应用程序的方式来运行的话，一定得处理单元头：&lt;/p&gt; &lt;p&gt;uses&lt;br&gt;&amp;nbsp; {$IFDEF RUNASAPP}&lt;br&gt;&amp;nbsp; Forms,&lt;br&gt;&amp;nbsp; {$ELSE}&lt;br&gt;&amp;nbsp; SvcMgr,&lt;br&gt;&amp;nbsp; {$ENDIF} &lt;p&gt;在这里，我的条件是RUNASAPP，在调试的时候，我就加上这个条件来编译，在正常发布的时候就把这个条件去掉。 &lt;p&gt;由于要调用服务的ServiceStart方法，所以得定义一个变量： &lt;p&gt;{$IFDEF RUNASAPP}&lt;br&gt;var&lt;br&gt;&amp;nbsp; b: Boolean;&lt;br&gt;{$ENDIF}&amp;nbsp; &lt;p&gt;同时，原来的应用程序代码也要改成：&lt;/p&gt; &lt;p&gt;Application.Initialize;&lt;br&gt;Application.CreateForm(TMyservice, MyService);&lt;br&gt;{$IFDEF RUNASAPP}&lt;br&gt;MyService.ServiceStart(nil, b);&lt;br&gt;{$ENDIF}&lt;br&gt;Application.Run;&lt;br&gt;{$IFDEF RUNASAPP}&lt;br&gt;Readln;&lt;br&gt;{$ENDIF} &lt;p&gt;加Readln的目标是不让ServiceStart完成后，就退出程序。 &lt;p&gt;这下，服务也可以和应用程序一样的，按F9后开始调试。&lt;/p&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/10007.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>在Windows NT Services中使用ADOConnection</title><link>http://webuc.net/chinahuman/archive/2008/06/14/10005.aspx</link><pubDate>Sat, 14 Jun 2008 12:08:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2008/06/14/10005.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/10005.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2008/06/14/10005.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/10005.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/10005.aspx</trackback:ping><description>&lt;p&gt;在开发windows服务的时候，想要连接数据库，可是发现在创建的时候就出错了，看看VCL里面的ADO创建的代码，发现是基于COM的调用的：&lt;/p&gt; &lt;p&gt;FConnectionObject := CreateADOObject(CLASS_Connection) as _Connection;&lt;br&gt;OleCheck(ConnectionPoint.Advise(Self as IUnknown, FConnEventsID));  &lt;p&gt;所以得在服务启动的时候，初始化一下COM：&lt;/p&gt; &lt;p&gt;CoInitialize(nil);  &lt;p&gt;对应的，在服务停止的时候，需要：&lt;/p&gt; &lt;p&gt;CoUninitialize;&lt;/p&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/10005.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>在服务里面弹出一个窗口到用户的桌面上</title><link>http://webuc.net/chinahuman/archive/2008/05/04/9966.aspx</link><pubDate>Sun, 04 May 2008 07:17:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2008/05/04/9966.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/9966.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2008/05/04/9966.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/9966.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/9966.aspx</trackback:ping><description>&lt;P&gt;曾几何时，服务里面弹出一个窗口到桌面上不再是那么地容易了：以前只要把服务设置为允许和桌面交互就可以直接在服务启动的时候，把一个窗口弹给用户。但是现在在vista(其它的OS 下没有测试，未知)下要弹出这样的窗体，首先会弹出一个提示框提示是否接否一个服务弹出来的消息，点接受后，才会在一个全灰的桌面里面弹出这个窗口。不用想，这样的用户体验，肯定是会被直接PASS。原因很简单，因为不同的用户间的桌面是不一样的，服务用的是System的权限，在vista里面是Session0，而用户的帐户不是这个（肯定大于0）。&lt;/P&gt;
&lt;P&gt;看来，想弹出一个窗体，需要另一个程序来作辅助了。解决方案有两种：&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;开发一个程序A在启动的时候，随系统启动，并监控指定文件M，服务S有消息的时候，放在文件M里，A 感受了文件变化了，就去读这个文件里的内容，根据规则来作对应的动作。坏处很明显，当用户为了让系统跑得快的时候，这种自启动文件很容易被砍掉，导致了有些功能莫名奇妙地不可用。 
&lt;LI&gt;同样地，也是开发一个程序A，用CreateProcessAsUser这个API来创建这个A ，并且发送到用户的桌面上去。好处是可以把这个A和服务S 放在同一个程序文件里面，根据不同的参数来启动不同的功能。这样用户除非是删除整个服务，否则不会有部分功能能用，又有部分功能不能用的问题。&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;现在来看看第二种方案，要想用CreateProcessAsUser这个API ，有这样几个步骤：&lt;/P&gt;
&lt;P&gt;１.取得用户的令牌（Token）&lt;/P&gt;
&lt;P&gt;２.指定好虚拟桌面&lt;/P&gt;
&lt;P&gt;３.调用API创建这个用户进程。&lt;/P&gt;
&lt;P&gt;在取得用户令牌的时候，又有几个方法：&lt;/P&gt;
&lt;P&gt;１.从用户的进程上去剥&lt;/P&gt;
&lt;P&gt;２.先用WTSGetActiveConsoleSessionId得到用户会话ID，再用WTSQueryUserToken这个API去取。&lt;/P&gt;
&lt;P&gt;不过在vista下面,服务里面的WTSGetActiveConsoleSessionId这个API得到的总是0，也就是Session0,用这个创建出来的进程，还是属于一个服务进程。(而且这个API是XP以及以后的系统才会提供的，在早点的系统上就会调用失败)所以我们只好从用户的进程上去找，用户登录的时候，一定会有的进程就是：explorer.exe，这样可以遍历所有的进程去找到这个（如果是多人同时登录这个系统里，我也不知道该怎么办了，不知道有没有高人指点一下）。&lt;/P&gt;
&lt;P&gt;这样创建出来的用户进程，在进程列表里面可以看到是活动用户的。但是如果在这里面使用一下文件选择框，或是去取一些系统目录，比如说用户的桌面，用户的收藏夹等，都会得到空。这时候因为没有指定用户环境造成的。使用CreateEnvironmentBlock这个API就可以搞定了。&lt;/P&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/9966.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>从一个灾难性故障引起的想聊聊delphi里的string</title><link>http://webuc.net/chinahuman/archive/2008/04/25/9953.aspx</link><pubDate>Fri, 25 Apr 2008 18:18:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2008/04/25/9953.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/9953.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2008/04/25/9953.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/9953.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/9953.aspx</trackback:ping><description>&lt;p&gt;用delphi搞了一个小服务，来实现多线程，可断点续传地上下载文件。所有的小块单独跑的时候，都非常正常，但是组装在一起的时候，突然内存暴长一下子占用了1G，引起了缓存的大量开销，频繁的IO读写引起了low CPU的情况下面的系统无法响应。开始的时候以为是里面的一些内存流没有释放引起的，review了一下代码确认没有问题。所以只好让系统再卡一次，把调试器挂到正在跑的服务上。突然发现以下的代码在运行时候，有异常情况出现：&lt;/p&gt; &lt;p&gt;var&lt;br&gt;&amp;nbsp; packagesStr: string;&lt;br&gt;&amp;nbsp; I: Integer;&lt;br&gt;begin&lt;br&gt;&amp;nbsp; if Length(FPackages) = 0 then&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; packagesStr := ''&lt;br&gt;&amp;nbsp; else begin&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetLength(packagesStr, Length(FPackages));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for I := 0 to Length(FPackages) -1 do&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; packagesStr[I ] := chr(byte(FPackages[I]) + 65);&lt;br&gt;&amp;nbsp; end;&lt;/p&gt; &lt;p&gt;FPackages 是一个记录每个文件包的状态的枚举值，想要把它系列化后保存起来，为了效率起见，所以用了这么一个小技巧（具体的，让我留到后面再讲）。本来才80几个包，结果在这里的字串长度长得惊人。然后很快地发现了问题：&lt;/p&gt; &lt;p&gt;packagesStr[I ] := chr(byte(FPackages[I]) + 65);&lt;br&gt;应该是&lt;/p&gt; &lt;p&gt;packagesStr[I + 1 ] := chr(byte(FPackages[I]) + 65);&lt;br&gt;因为当I=0的时候，引入第一个值：65，把这个字串的指针搞乱了，所以引起了海量内存的使用。&lt;/p&gt; &lt;p&gt;好了，让我们先看看delphi里面的string的结构吧：&lt;/p&gt; &lt;p&gt;string是一个比较有意思的类型，它不仅仅是一个字串那么简单。它的结构的开始是一个指针，指向了直正字串开始的地址，所以sting有一个copy on write的特性，也就是说当字串赋值的时候，两个串都是指向同一个内存块（也就是string[1]这个地址），但是如果串被改的时候，就会复制一份出来改。&lt;/p&gt; &lt;p&gt;再来说说我的这个小技巧：因为我这里可能有几十个包，所以保存成字串的时候，如果是一段一段地加起来，到时候会产生大量的临时变量，引起性能的问题。所以我预算了一下它需要多长，就先把这个长度开出来，然后按位地去赋值。&lt;/p&gt; &lt;p&gt;string还有一个妙用是可以当成stream来使用。以前找了一个base64加密的类，它的参数只能传string，而我想要把一副图片转成base64好让它能在IE里面方便地传到服务器上。于是我就把这个图片读到了一个string里面：&lt;/p&gt; &lt;p&gt;var&lt;br&gt;&amp;nbsp; stream: TMemoryStream;&lt;br&gt;&amp;nbsp; imagestr: string;&lt;br&gt;begin&lt;br&gt;&amp;nbsp; with TJPEGImage.Create do&lt;br&gt;&amp;nbsp; try&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assign(FCurrDrawingPad);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CompressionQuality := 80;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream := TMemoryStream.Create;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SaveToStream(stream);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetLength(imagestr, stream.Size);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream.Position := 0;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream.Read(imagestr[1], stream.Size);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := StrTobase64(imagestr);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream.Free;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br&gt;&amp;nbsp; finally&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Free;&lt;br&gt;&amp;nbsp; end;&lt;img src ="http://webuc.net/chinahuman/aggbug/9953.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>终于发现IIS7的好处了</title><link>http://webuc.net/chinahuman/archive/2007/11/02/9567.aspx</link><pubDate>Fri, 02 Nov 2007 14:14:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2007/11/02/9567.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/9567.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2007/11/02/9567.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/9567.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/9567.aspx</trackback:ping><description>&lt;P&gt;最近IronSoft系列组件又出了一些小问题,比如说GIFBuilder在自己创建GIF的时候,竟然发现只有第一帧有延时,后面的没有延时.在给每帧增加延时的时候,突然发现IIS报错了.一看这种错误老铁一般都很头大,因为IIS没有办法调试这样的问题,只能是和JS一样摸黑着来.&lt;/P&gt;
&lt;P&gt;突然想起来好像现在装的是IIS7,不知道有改进没有.于是把DELPHI附加到了IIS7的W3WP.exe进程上,运行网页的时候,发现DELPHI竟然有响应,而且报出了一个错误,一看果真是我的代码错了-_-,这个错误一直都有,不知道为什么到现在才发现.于是在组件的代码上加断点,竟然可以正确地停下并进行调试了.&lt;/P&gt;
&lt;P&gt;有了调试器的帮助,我只有十来分钟就找到了问题所在,并修正,感觉好爽:)IIS7终于感觉比以前的版本有点用了.&lt;/P&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/9567.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>Delphi里的一些需要注意的问题</title><link>http://webuc.net/chinahuman/archive/2007/09/11/9400.aspx</link><pubDate>Tue, 11 Sep 2007 08:10:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2007/09/11/9400.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/9400.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2007/09/11/9400.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/9400.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/9400.aspx</trackback:ping><description>&lt;p&gt;又发现了一些问题,记录下来,和大家分享:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;在写DLL的时候,一定要在主程序和DLL工程里面都引用内存管理器,比如说BolandMM(宝兰MM),不过我比较推荐FastMM,因为这个内存管理器效率高，而且可以监控到有没有内存泄露的问题，同时可以在发行包里省掉BolandMM.dll。之所以发现这个问题，应该从一个郁闷了我三天的问题说起，在DLL里面执行存储过程的时候，发现一直提示“不正常地定义参数对象。提供了不一致或不完整的信息。”而用SQL事件探寻器，并没有发现程序调用了存储过程。通过大量的跟踪分析后才发现是犯的一个低级错误。&lt;/li&gt; &lt;li&gt;当定一个对象的时候，还没有创建这个对象的时候去访问它，竟然不会报内存保护错误，而是随便扔了一个对象过来，这个问题也郁闷了我好久。&lt;/li&gt; &lt;li&gt;调用存储过程的时候，一定要注意参数的顺序，发现参数的名字只是在程序里面用到，事实上没有传到SQL SERVER上面,只是把参数值按顺序依次传到SQL Server上，如果忽视参数顺序的问题，到时候就有的郁闷了。&lt;/li&gt; &lt;li&gt;用Excel来生成代码：）。要把表生成存储过程和生成对应的对象代码以及初始化保存什么的代码，是一个繁杂而且还容易出错的过程，一个简单的办法就是把表设计拷出来，贴到Excel里，然后用字串函数拼出我们想要的代码。&lt;/li&gt;&lt;/ol&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/9400.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>Delphi一些小结</title><link>http://webuc.net/chinahuman/archive/2007/09/10/9393.aspx</link><pubDate>Mon, 10 Sep 2007 16:27:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2007/09/10/9393.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/9393.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2007/09/10/9393.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/9393.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/9393.aspx</trackback:ping><description>&lt;p&gt;好久没有像模像样地写DELPHI的程序了,最近写了一些,发现了一些以前没有碰到过的问题,以及小技巧:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;封装数据库访问层时,可以用一个先定义一个数据访问接口(如IDataProvider),然后实现封在DLL里面,这样轻松实现在不同的数据库之间切换程序的数据源(实现一个和ASP.NET很类似的Provider模式).&lt;/li&gt; &lt;li&gt;在使用存储过程的时候,对一字串类型的值,一定要指明参数所需要的长度,否则会丢数据,赋值的时候,他会把中文按一个字算,但是在执行的时候,中文会当成两个字来算(这个和.NET比起来差别真大).&lt;/li&gt; &lt;li&gt;为了保持控件和对象的关系,可以把对象的指针挂在控件的Data属性里面,但是注意,有些控件的在释放的时候,会顺路帮你把对象释放了,所以在作内存释放的时候,一定要注意顺序,一定要把对象先放了,再删除控件(或是对象释放前先判断一下还存在不).&lt;/li&gt; &lt;li&gt;对象不是生存期自管理的,所以一定要注意,不然就会有内存泄露,我的作法是创建的时候,顺路就挂到那些ObjectList上,当然得注意,一个对象只能让一个ObjectList管理,不然程序退出的时候,又是一堆错.&lt;/li&gt; &lt;li&gt;因为数据有多个层次,多种目录,所以加载的时候,我开始选择打开一个目录加载一层,后面发现这种方式太复杂了,控制代码写得吐血.后面想到了,把原来的大对象拆成为:小对象+大对象的方式,小对象一次性加载完成(我这里的数据估计就几万条,算一下估计是能占个三五M的内存吧),大对象用懒加载的方式,这样即让控制简单,同时也不会造成加载的时候,速度偏慢和占用内存过多的问题.&lt;/li&gt; &lt;li&gt;如果在显示图片的时候,希望在图像区域出现滚动条,那么可以先把图片控件放在一个Frame里,然后再把这个Frame放到需要显示的地方,固定好Frame的大小,就可以了.原理是:其实显示的滚动条是Frame的.&lt;/li&gt; &lt;li&gt;计划完成DataValidator,这样只要注册一下控件的事情校验要求,就可以轻松实现界面控件的校验需求.&lt;/li&gt;&lt;/ol&gt;&lt;img src ="http://webuc.net/chinahuman/aggbug/9393.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>铁匠</dc:creator><title>开始把GDI+引入到Delphi中来</title><link>http://webuc.net/chinahuman/archive/2007/08/07/9255.aspx</link><pubDate>Tue, 07 Aug 2007 17:43:00 GMT</pubDate><guid>http://webuc.net/chinahuman/archive/2007/08/07/9255.aspx</guid><wfw:comment>http://webuc.net/chinahuman/comments/9255.aspx</wfw:comment><comments>http://webuc.net/chinahuman/archive/2007/08/07/9255.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/chinahuman/comments/commentRss/9255.aspx</wfw:commentRss><trackback:ping>http://webuc.net/chinahuman/services/trackbacks/9255.aspx</trackback:ping><description>最近在写一个小控件,涉及到复杂的坐标变换,以及旋转之类的,现在三角函数都记不全了,作这个实在是痛苦.突然想到了.NET中的图片处理已经使用了GDI+了,里面的坐标变换之类的应该是GDI+的一些API.于是找来Reflector把System.Drawing这个DLL反编,查看源码,果真是从GDIplus.dll这个库里导出来的.GdipRotateWorldTransform 这个实现了坐标系的旋转,GdipTranslateWorldTransform这个实现了坐标系的平移...&lt;br&gt;
不过在处理写文字串的时候GdipDrawString,碰到了麻烦:里面的字体什么的还要引用其它的API(GdipCreateFontFamilyFromName,GdipCreateFont)来生成.在使用GdipCreateFontFamilyFromName的时候,发现生成的FontFamily一直是空的,比较奇怪,最后发现.NET里面实现的时候,导入的字符集已经由以前常见的Ansi变成Unicode了,于是把字体名称的字符转成Unicode编码后搞定。得到一个提示，里面的所有字串的都是需要Unicode编码。&lt;br&gt;
不过比较郁闷的事情是生成的图片一直是空白的，跟踪每一步API的使用返回的值都是OK。还得要一袋烟功夫来研究。&lt;img src ="http://webuc.net/chinahuman/aggbug/9255.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>