home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / PBBSW35 / DISK2.PWR / POWRDLL.C < prev    next >
C/C++ Source or Header  |  1994-07-17  |  32KB  |  960 lines

  1. /****************************************************************************/
  2. /* PowerBBS Development Add-On DLL                        */
  3. /* (c) 1994 by Russell E. Frey                            */
  4. /*                                        */
  5. /* This source code may be freely distributed.                    */
  6. /* You may create a 3rd party DLL add-on to PowerBBS, and            */
  7. /* distribute it ROYALTY FREE.                            */
  8. /*                                        */
  9. /* You may even modify this code and distribute it, so long as you        */
  10. /* note the modifications at the top of the code and keep ALL the        */
  11. /* comments here at the top.                            */
  12. /*                                        */
  13. /* Be sure to announce your product on our BBS: 516-822-7396 and/or        */
  14. /* distribute shareware versions of your DLL on our BBS.  We will do        */
  15. /* our best to help you distribute your product!                */
  16. /*                                        */
  17. /* If you translate this code to a different language, please consider        */
  18. /* making your translation FREEWARE and upload it to the BBS.  Be sure        */
  19. /* to thoroughly debug your translation (you do not want to mess up        */
  20. /* the users record or they will not be happy!)                    */
  21. /*                                        */
  22. /* Sample code in Borland Pascal 7.0 on writing an add-on DLL for PowerBBS  */
  23. /*                                        */
  24. /* This code can easily be translated to ANY language capable to make a DLL */
  25. /* To run this DLL, in PowerBBS MENU SETUP at the CGM option place a D [For */
  26. /* DLL!].  Then in the description of command put the NAME of the actual    */
  27. /* DLL created.  For example this file: POWRDLL.DLL would be placed in        */
  28. /* the description.                                */
  29. /*                                        */
  30. /* When a user now selects the command PowerBBS will dynamically load        */
  31. /* POWRDLL.DLL.  It will execute VERY FAST.  This is an easy way to create  */
  32. /* a 3rd party add-on as if it was written inside of PowerBBS!  The user    */
  33. /* will notice NO SLOWDOWN!                            */
  34. /*                                        */
  35. /* PowerLang's RUN_DLL command may also be used to execute the DLL        */
  36. /*                                        */
  37. /* We welcome ALL your comments on the Power of PowerBBS's DLL            */
  38. /* We also welcome any questions you might have, but due to time        */
  39. /* constraints may not be able to help you in some cases (including        */
  40. /* debugging your code, etc).                            */
  41. /*                                        */
  42. /* Be aware that this product is provided AS IS.  We are not            */
  43. /* liable for ANY problems this DLL may cause.                    */
  44. /*                                        */
  45. /****************************************************************************/
  46.  
  47. /****************************************************************************/
  48. /*                                        */
  49. /* PowerBBS Development Add-On DLL                        */
  50. /* (c) 1994 by Russell E. Frey                            */
  51. /*                                        */
  52. /****************************************************************************/
  53.  
  54. #include <windows.h>
  55. #include <stdlib.h>
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include "powrdll.h"
  59.  
  60. /****************************************************************************/
  61. /* Note to 'C' programmers:                                                 */
  62. /* You should have knowledge about the special behavior of a DLL. Remember  */
  63. /* that multiple instances of a DLL share the same data segment so that if  */
  64. /* you make a DLL that can be called by several nodes at the same time you  */
  65. /* will need to take into acount that all nodes will use the same data.     */
  66. /* You can handle this by using arays for the data that is to be unique     */
  67. /* for each node and use the node number to index into the data. Since      */
  68. /* PowerBBS can handle up to nine nodes plus another 15 Telnet nodes you    */
  69. /* would need to have a lot of static data allocated that in most cases     */
  70. /* would not be used. It may be better to allocate a structure dynamically  */
  71. /* as the DLL start up for a node and pass a pointer to this structure to   */
  72. /* all functions where the data would be needed.                            */
  73. /* Also remember that a DLL runs of the stack of the calling program. This  */
  74. /* means that you should be restrictive of using too much automatic         */
  75. /* variables and that such variables, if the address of these are passed    */
  76. /* to other functions, MUST be passed as FAR pointers.                      */
  77. /****************************************************************************/
  78.  
  79. // Need Colors?  Use the following in your Print_Modem calls:
  80. //
  81. //  @1@ Blue
  82. //  @2@ Green
  83. //  @3@ Cyan
  84. //  @4@ Red
  85. //  @5@ Magenta
  86. //  @6@ Gray
  87. //  @7@ Yellow
  88. //  @8@ Brown
  89. //  @9@ White
  90. //  @10@ Light Blue
  91. //  @11@ Light Green
  92. //  @12@ Light Cyan
  93. //  @13@ Light Red
  94. //  @14@ Light Magenta
  95. //  @15@ Light Gray
  96. //  @16@ Default Color
  97. //
  98. //  Colors will ONLY be used if the caller has ANSI capabilities.
  99.  
  100. HINSTANCE hInst;
  101.  
  102. // The LibMain function is called by Windows when it is loaded. If you
  103. // need to initialize anything, e.g., register a window class, here is
  104. // the place to do it.
  105. int FAR PASCAL LibMain (HANDLE hinstance, WORD wdataseg,
  106.                         WORD cbheapsize, LPSTR lpszcmdline)
  107. {
  108.     hInst = hinstance;
  109.     return 1;
  110. }
  111.  
  112. // The corresponding function, called by Windows when the DLL is unloaded
  113. // from memory.
  114.  
  115. int FAR PASCAL WEP (int nparamater)
  116. {
  117.     return(TRUE);
  118. }
  119.  
  120. //--------------------------------------------------------------------------
  121. // Support routine to convert an ASCII string to a numeric value. It is
  122. // similar to the atoi() function but can be used inside a small model
  123. // DLL with automatic variables since it is expecting a LPSTR (FAR *).
  124. //--------------------------------------------------------------------------
  125.  
  126. int asc_to_int (LPSTR pIn)
  127. {
  128.     LPSTR p = pIn;
  129.     int Value = 0;
  130.     
  131.     while ((* p) && (* p == ' ')) p ++;
  132.     while (* p)
  133.     {
  134.     if ((* p < '0') || (* p > '9'))
  135.         break;
  136.     Value *= 10;
  137.     Value += (int) ((* p) - '0');
  138.     p ++;
  139.     }
  140.     return Value;
  141. }
  142.  
  143. //--------------------------------------------------------------------------
  144. // Support function to convert a Pascal formated string to a null terminated
  145. // 'C' string. The function returns a pointer to the user suplied buffer
  146. // so that it may be used in functions that takes a string pointer as
  147. // an argument, e.g., wsprintf(). The pascal pointer should point to the
  148. // length byte of the string. The Max is the size of the allocated 'C'
  149. // string.
  150. //--------------------------------------------------------------------------
  151.  
  152. LPSTR PascalToCString (unsigned char FAR * PascalString, LPSTR CString,
  153.                unsigned int Max)
  154. {
  155.     unsigned int Len = * PascalString ++;
  156.     
  157.     Max --;
  158.     if (Max <= 0)
  159.     {
  160.     * CString = '\0';
  161.     return CString;
  162.     }
  163.     if (Len > Max)
  164.     Len = Max;
  165.     _fmemcpy (CString, PascalString, Len);
  166.     CString [Len] = '\0';
  167.     return CString;
  168. }
  169.  
  170. //--------------------------------------------------------------------------
  171. // Support function to convert a Pascal formated string to a null terminated
  172. // 'C' string. The function returns a pointer to the user suplied buffer
  173. // so that it may be used in functions that takes a string pointer as
  174. // an argument, e.g., wsprintf(). This function is used with Pascal strings
  175. // that does not have a length byte. The size should for this function be
  176. // the size of the string as declared in the structure.
  177. //--------------------------------------------------------------------------
  178.  
  179. LPSTR PackedToCString (LPSTR PackedString, LPSTR CString, int Size)
  180. {
  181.     if (Size <= 0)
  182.     {
  183.     * CString = '\0';
  184.     return CString;
  185.     }
  186.     _fmemcpy (CString, PackedString, Size);
  187.     CString [Size] = '\0';
  188.     return CString;
  189. }
  190.  
  191.  
  192. //--------------------------------------------------------------------------
  193. // Sample procedures to interface with PowerBBS.
  194. //--------------------------------------------------------------------------
  195.  
  196. void Print_Modem(HWND PBBSWin, LPSTR ToWrite)
  197. {
  198. // Prints the String TOWRITE to the screen and caller
  199.     SendMessage(PBBSWin, WM_COMMAND, PBBS_PRINTMODEM, (LONG) ToWrite);
  200. }
  201.  
  202. //--------------------------------------------------------------------------
  203. void PrintLn_Modem(HWND PBBSWin, LPSTR ToWrite)
  204. {
  205. // Prints the String TOWRITE followed by a carriage return to
  206. // screen and caller
  207.     char Temp [255];
  208.     lstrcpy (Temp, ToWrite);
  209.     lstrcat (Temp, "\r");
  210.     SendMessage(PBBSWin, WM_COMMAND, PBBS_PRINTMODEM, (LONG)(LPSTR) Temp);
  211. }
  212.  
  213. //---------------------------------------------------------------------------
  214. void Get_Enter_Key(HWND PBBSWin)
  215. {
  216. // Outputs to the user to press their enter key, waits till its pressed,
  217. // and clears the output that says Press [Enter]:
  218.  
  219.     SendMessage(PBBSWin, WM_COMMAND, PBBS_GET_ENTER, 0);
  220. }
  221.  
  222. //---------------------------------------------------------------------------
  223. void Ask_User(HWND PBBSWIN, LPSTR InputS, int MaxIn)
  224. {
  225. // Inputs characters from a user.
  226.  
  227.   char pIn[255];
  228.  
  229.   wsprintf (pIn, "%d", MaxIn);
  230.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_ASK_USER, (LONG)(LPSTR) pIn);
  231.   lstrcpy (InputS, pIn);
  232. // Note that command 10003 you send PowerBBS the maximum number of
  233. // input chars.  It then uses this SAME pointer to send back the
  234. // actual input from the user.
  235. }
  236.  
  237.  
  238. //---------------------------------------------------------------------------
  239. void ClearScreen(HWND PBBSWIN)
  240. {
  241. // Clears the ANSI screen 
  242.  
  243.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_CLS, 0);
  244. }
  245.  
  246. //---------------------------------------------------------------------------
  247. BOOL PauseStop(HWND PBBSWIN)
  248. {
  249. // this function will display ::: Pause [S]top, [C]ontinue ::: if
  250. // the user is beyond their max lines/page.  If the user presses
  251. // S to Stop this function returns TRUE.  Otherwise FALSE is
  252. //  pressed
  253.  
  254.   char pIn [255];
  255.  
  256.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_PAUSE_STOP, (LONG)(LPSTR) pIn);
  257.   if (pIn[0] == 'Y')
  258.       return TRUE;
  259.   return FALSE;
  260. }
  261.  
  262. //---------------------------------------------------------------------------
  263. char Get_Key(HWND PBBSWIN)
  264. {
  265. // Waits for a key from the user.  Returns the key pressed (note that
  266. // if the carrier dropped carrier it returns char #255).
  267. //  *RETURNS THE UPPERCASE CHARACTER OF KEYPRESSED*
  268.  
  269.   char pIn [6];
  270.  
  271.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_GET_KEY, (LONG)(LPSTR) pIn);
  272.   return (pIn[0] & 0xFF);
  273. }
  274.  
  275.  
  276. //---------------------------------------------------------------------------
  277. BOOL Get_YN(HWND PBBSWIN)
  278. {
  279. // Waits until the user presses Yes or No.  (note that it COULD be
  280. // different from a Y if a different LANGUAGE is being used)
  281.     
  282.   char pIn[6];
  283.  
  284.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_GET_YN, (LONG)(LPSTR) pIn);
  285.   if (pIn [0] == 'Y')
  286.       return TRUE;
  287.   return FALSE;
  288. }
  289.  
  290. //---------------------------------------------------------------------------
  291. BOOL Get_YesNoQ(HWND PBBSWIN, LPSTR TheQues, BOOL Default)
  292. {
  293. // Outputs the question THEQUES to the user.  Then waits for a Y/N answer,
  294. // with Default being the answer if the user presses the [ENTER] key.
  295. // Returns the result 
  296.  
  297.     char PIn [255];
  298.  
  299.     if (Default)
  300.     lstrcpy (PIn, "Y");
  301.     else
  302.     lstrcpy (PIn, "N");
  303.     lstrcat (PIn, TheQues);
  304.     
  305.     SendMessage(PBBSWIN, WM_COMMAND, PBBS_GET_YNQ, (LONG)(LPSTR) PIn);
  306.     if (PIn [0] == 'Y')
  307.     return TRUE;
  308.     return FALSE;
  309. }
  310.  
  311. //---------------------------------------------------------------------------
  312. char Get_Hot(HWND PBBSWIN, LPSTR OKChars)
  313. {
  314. // Waits till the user presses a valid char in the OKChars string and
  315. // returns that char (note: may not return a valid char if the user
  316. // drops carrier).  Ex: Get_Hot(PBBSWIN, 'YN') to wait for Y or N.
  317. //  Use UPPERCASE
  318.  
  319.     char PIn [255];
  320.  
  321.   lstrcpy (PIn, OKChars);
  322.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_GET_HOT, (LONG)(LPSTR) PIn);
  323.   return PIn [0];
  324. }
  325.  
  326. //---------------------------------------------------------------------------
  327. void Type_File_To_Modem (HWND PBBSWIN, LPSTR FName)
  328. {
  329. // Types the file specified to the modem.
  330.  
  331.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_TYPE_FILE, (LONG) (LPSTR) FName);
  332. }
  333.  
  334. //---------------------------------------------------------------------------
  335. char Input_Key_Time(HWND PBBSWIN, int MaxTime)
  336. {
  337. // Waits up to MaxTime (in milliseconds) for a character to be entered.
  338. // If the user does NOT press a key in this time, character #255 is
  339. // returned. 
  340.     
  341.  
  342.     char PIn [255];
  343.     wsprintf (PIn, "%d", MaxTime);
  344.     SendMessage(PBBSWIN, WM_COMMAND, PBBS_TIMED_KEY, (LONG)(LPSTR) PIn);
  345.     return PIn [0];
  346. }
  347.  
  348.  
  349. //---------------------------------------------------------------------------
  350. void Send_Modem_Command(HWND PBBSWIN, LPSTR commands)
  351. {
  352. // Sends commands to the modem and does NOT print commands on the local
  353. //  screen.
  354.  
  355.     SendMessage(PBBSWIN, WM_COMMAND, PBBS_MODEM_CMD, (LPARAM)(LPSTR) commands);
  356. }
  357.  
  358.  
  359. //--------------------------------------------------------------------------
  360. BOOL No_User_Online(HWND PBBSWIN)
  361. {
  362. //  This is an IMPORTANT function.  If this boolean is ever TRUE it should
  363. //  be the end of your DLL!  So this NEEDS to be included in all loops,
  364. //  repeats, etc.  If TRUE, then exit the loop, etc..  Example:
  365. //    Repeat
  366. //    Until (..) or (No_User_Online);
  367.  
  368.  
  369.     char pIn [6];
  370.  
  371.     SendMessage(PBBSWIN, WM_COMMAND, PBBS_NOT_ONLINE, (LONG)(LPSTR) pIn);
  372.     if (pIn [0] == 'Y')
  373.     return TRUE;
  374.     return FALSE;
  375. }
  376.  
  377. //---------------------------------------------------------------------------
  378. void Execute_Prog(HWND PBBSWIN, LPSTR commands)
  379. {
  380. //  Closes the com port.  Executes commands, re-opens, and returns.
  381.  
  382.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_EXEC_PRG, (LPARAM)(LPSTR) commands);
  383. }
  384.  
  385. //---------------------------------------------------------------------------
  386. BOOL Key_Waiting(HWND PBBSWIN)
  387. {
  388. // Returns true if a key is waiting (could be either from the sysop's
  389. //  local keyboard or remote
  390.  
  391.     char pIn [6];
  392.  
  393.     SendMessage(PBBSWIN, WM_COMMAND, PBBS_KEY_WAITING, (LONG)(LPSTR) pIn);
  394.     if (pIn[0] == 'Y')
  395.     return TRUE;
  396.     return FALSE;
  397. }
  398.  
  399. //---------------------------------------------------------------------------
  400. void Verify_Time_Left(HWND PBBSWIN)
  401. {
  402. // PowerBBS checks the time left by User.  If it is 0, the user is
  403. // told their time is out.   (No_User_Online would then be TRUE).
  404.  
  405.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_VERIF_TIME, 0L);
  406. }
  407.  
  408. //--------------------------------------------------------------------------
  409. int Time_Left(HWND PBBSWIN)
  410. {
  411. // Returns the time that the user has left
  412.  
  413.   char pIn [255];
  414.  
  415.   SendMessage(PBBSWIN, WM_COMMAND, PBBS_TIME_LEFT, (LONG)(LPSTR) pIn);
  416.   return (asc_to_int (pIn));
  417. }
  418.  
  419. //--------------------------------------------------------------------------
  420.  
  421. void Write_ActLog(HWND PBBSWIN, LPSTR ToWrite)
  422. {
  423. // Writes TOWRITE to the activity Log 
  424.   SendMessage(PBBSWIN, WM_COMMAND, 10019, (LONG) ToWrite);
  425. }
  426.  
  427. //---------------------------------------------------------------------------
  428. void Convert_Macros(HWND PBBSWIN, LPSTR ToConv)
  429. {
  430. // Converts all |MACROS|
  431.     SendMessage(PBBSWIN, WM_COMMAND, 10020, (LONG) (LPSTR) ToConv);
  432. }
  433.  
  434. //--------------------------------------------------------------------------
  435. void Change_Forum(HWND PBBSWIN, int InI)
  436. {
  437. // Change to Forum InI
  438.  
  439.     char pIn [254];
  440.  
  441.     wsprintf (pIn, "%d", InI);
  442.     SendMessage(PBBSWIN, WM_COMMAND, 10021, (LPARAM)(LPSTR) pIn);
  443. }
  444.  
  445.  
  446. //{--------------------------------------------------------------------------
  447. void Run_Menu_Command(HWND PBBSWIN, int InI)
  448. {
  449. // Run_Menu_Command InI 
  450.  
  451.     char pIn [254];
  452.  
  453.     wsprintf (pIn, "%d", InI);
  454.     SendMessage(PBBSWIN, WM_COMMAND, 10022, (LPARAM)(LPSTR) pIn);
  455. }
  456.  
  457. //---------------------------------------------------------------------------
  458. void Run_PowerBase(HWND PBBSWIN, int InI)
  459. {
  460. // Run PowerBase InI
  461.     
  462.     char pIn[254];
  463.  
  464.     wsprintf (pIn, "%d", InI);
  465.     SendMessage(PBBSWIN, WM_COMMAND, 10023, (LPARAM)(LPSTR) pIn);
  466. }
  467.  
  468.  
  469. //---------------------------------------------------------------------------
  470. void Back_Spaces(HWND PBBSWIN, int Num)
  471. {
  472. // This procedure is used to back up and clear text.  For example you could
  473. // use: Press [ENTER]: then after ENTER is pressed, used this procedure to
  474. //  back up
  475.     
  476.     char pIn[254];
  477.  
  478.     wsprintf (pIn, "%d", Num);
  479.     SendMessage(PBBSWIN, WM_COMMAND, 10025, (LPARAM)(LPSTR) pIn);
  480. }
  481.  
  482. //---------------------------------------------------------------------------
  483. void Send_File(HWND PBBSWIN, LPSTR Fname, int mode)
  484. {
  485. // Sends filename FNAME [be sure to include full path/filename!]
  486. //  Mode:
  487. //    1: zmodem
  488. //    2: xmodem/crc
  489. //    3: xmodem/1k
  490. //    4: xmodem/1kg
  491. //    5: ymodem
  492. //    6: ymodemg
  493. //    7: kermit    
  494.  
  495.     char pIn[254];
  496.     wsprintf (pIn, "%d~%s", mode, (LPSTR)Fname);
  497.     SendMessage(PBBSWIN, WM_COMMAND, 10026, (LPARAM)(LPSTR) pIn);
  498. }
  499.  
  500. //---------------------------------------------------------------------------
  501. void Receive_File(HWND PBBSWIN, LPSTR Fname, int mode)
  502. {
  503. // Receives Fname.  Only uses the FILENAME in Fname.  The file
  504. // is placed in the transfer directory.  BBS_RECORD.Transfer_Dir
  505. //  Mode:
  506. //    1: zmodem
  507. //    2: xmodem/crc
  508. //    3: xmodem/1k
  509. //    4: xmodem/1kg
  510. //    5: ymodem
  511. //    6: ymodemg
  512. //    7: kermit
  513.     
  514.     char pIn [254];
  515.     
  516.     wsprintf (pIn, "%d~%s", mode, (LPSTR)Fname);
  517.     SendMessage(PBBSWIN, WM_COMMAND, 10027, (LPARAM)(LPSTR) pIn);
  518. }
  519.  
  520. //---------------------------------------------------------------------------
  521. char Monitor_Mode(HWND PBBSWIN)
  522. {
  523. // Returns the color mode:
  524. //  'R' = RIP
  525. //  'C' = ANSI
  526. //  'M' = ASCII
  527. //  Note that RIP is also ANSI compatible.
  528.  
  529.     char pIn [11];
  530.  
  531.     SendMessage(PBBSWIN, WM_COMMAND, 10028, (LPARAM)(LPSTR) pIn);
  532.     return pIn[0];
  533. }
  534.  
  535. //-------------------------------------------------------------------------
  536. LPPOWRUSER_RECORD Get_UserRec(HWND PBBSWIN)
  537. {
  538. //  Gives you the pointer to the actual location of the user record in memory.
  539. //  By changing the actual information in this record you are able to change
  540. //  the current user information!  (BE CAREFUL ON WHAT YOU DO!)
  541.  
  542.     
  543.     LPPOWRUSER_RECORD  lpUser;
  544.     char pIn [254];
  545.     
  546.     SendMessage(PBBSWIN, WM_COMMAND, 10030, (LPARAM)(LPSTR) pIn);
  547.     lpUser = (LPPOWRUSER_RECORD) * (LONG *) pIn;
  548.     return lpUser;
  549. }
  550.  
  551. //---------------------------------------------------------------------------
  552. LPPOWRUSER_RECORD_EXTENSION Get_ForumUserRec(HWND PBBSWIN)
  553. {
  554. //  Gives you the pointer to the actual location of the user forum record in
  555. //  memory.  This record contains the user's last read pointers along with
  556. //  the information containing which forums the user has access to.
  557.  
  558.  
  559.     LPPOWRUSER_RECORD_EXTENSION  lpExt;
  560.     char pIn [254];
  561.     
  562.     SendMessage(PBBSWIN, WM_COMMAND, 10031, (LPARAM)(LPSTR) pIn);
  563.     lpExt = (LPPOWRUSER_RECORD_EXTENSION) * (LONG *) pIn;
  564.     return lpExt;
  565. }
  566.  
  567. //---------------------------------------------------------------------------
  568. LPPOWER_CALLINFO_REC Get_CallInfo(HWND PBBSWIN)
  569. {
  570. //  Gives you the pointer to the actual location of the caller info record in
  571. //  memory.
  572.     
  573.     LPPOWER_CALLINFO_REC lpCallInf;
  574.     char pIn [254];
  575.  
  576.     SendMessage(PBBSWIN, WM_COMMAND, 10032, (LPARAM)(LPSTR) pIn);
  577.     lpCallInf = (LPPOWER_CALLINFO_REC) * (LONG *) pIn;
  578.     return lpCallInf;
  579. }
  580.  
  581.  
  582. //---------------------------------------------------------------------------
  583. LPPOWERBBS_FORUM_STRUCTURE Get_Current_ForumInfo(HWND PBBSWIN)
  584. {
  585.     
  586.     LPPOWERBBS_FORUM_STRUCTURE  lpForum;
  587.     char pIn [254];
  588.     
  589.     SendMessage(PBBSWIN, WM_COMMAND, 10033, (LPARAM)(LPSTR) pIn);
  590.     lpForum = (LPPOWERBBS_FORUM_STRUCTURE) * (LONG *) pIn;
  591.     return lpForum;
  592. }
  593.  
  594. //--------------------------------------------------------------------------
  595. LPPBBSRECORD Get_BBS_Record(HWND PBBSWIN)
  596. {
  597.     
  598.     LPPBBSRECORD  lpBBSRec;
  599.     char pIn [254];
  600.  
  601.     SendMessage(PBBSWIN, WM_COMMAND, 10034, (LPARAM)(LPSTR) pIn);
  602.     lpBBSRec = (LPPBBSRECORD) * (LONG *) pIn;
  603.     return lpBBSRec;
  604. }
  605.  
  606.  
  607. //---------------------------------------------------------------------------
  608. void End_Call(HWND PBBSWIN)
  609. {
  610. // End The Call
  611.  
  612.     SendMessage(PBBSWIN, WM_COMMAND, 10024, 0);
  613. }
  614.  
  615. //--------------------------------------------------------------------------
  616. int Search_UserName(HWND PBBSWIN, LPSTR TheName)
  617. {
  618. // Searches the UserDatabase for TheName.  If not found, returns 0.
  619. //  If found, returns the record number that TheName is contained within. }
  620.  
  621.     char pIn[254];
  622.  
  623.     lstrcpy (pIn, TheName);
  624.     SendMessage(PBBSWIN, WM_COMMAND, 10040, (LPARAM)(LPSTR) pIn);
  625.     return (asc_to_int (pIn));
  626. }
  627.  
  628. //--------------------------------------------------------------------------
  629. void Load_UserRec(HWND PBBSWIN, LPPOWRUSER_RECORD user, int usernum)
  630. {
  631. //  You must allocate memory for user before calling this routine!
  632. //  UserNum signifies the actual user record number (ask returned
  633. //  by Search_UserName)
  634.  
  635.     char pIn [254];
  636.  
  637.     wsprintf (pIn, "%d", usernum);
  638.     SendMessage(PBBSWIN, WM_COMMAND, 10041, (LPARAM)(LPSTR) pIn);
  639.     SendMessage(PBBSWIN, WM_COMMAND, 10042, (LPARAM)(LPSTR) user);
  640. }
  641.  
  642. //---------------------------------------------------------------------------
  643. void Save_UserRec(HWND PBBSWIN, LPPOWRUSER_RECORD user, int usernum)
  644. {
  645. //  You must allocate memory for user before calling this routine!
  646. //  UserNum signifies the actual user record number (as returned
  647. //  by Search_UserName)
  648.  
  649.     char pIn [254];
  650.  
  651.  
  652.     wsprintf (pIn, "%d", usernum);
  653.     SendMessage(PBBSWIN, WM_COMMAND, 10041, (LPARAM)(LPSTR) pIn);
  654.     SendMessage(PBBSWIN, WM_COMMAND, 10043, (LPARAM)(LPSTR) user);
  655. }
  656.  
  657. //---------------------------------------------------------------------------
  658. void Close_ComPort(HWND PBBSWIN)
  659. {
  660. // Closes the com port.
  661.  
  662.     SendMessage(PBBSWIN, WM_COMMAND, 10044, 0);
  663. }
  664.  
  665. //---------------------------------------------------------------------------
  666. void Open_ComPort(HWND PBBSWIN)
  667. {
  668. // Opens up the Com Port.
  669.  
  670.     SendMessage(PBBSWIN, WM_COMMAND, 10045, 0);
  671. }
  672.  
  673. //---------------------------------------------------------------------------
  674. void HangUp_Caller(HWND PBBSWIN)
  675. {
  676. // Attempts to hangup the caller.
  677. //  (Note that after 4 tries it gives up, if the caller is still on-line)
  678.  
  679.     SendMessage(PBBSWIN, WM_COMMAND, 10046, 0);
  680. }
  681.  
  682. //---------------------------------------------------------------------------
  683. int Number_Users_Online(HWND PBBSWIN)
  684. {
  685. // Returns the number of users currently on-line.
  686. // Only returns NON-ZERO nodes (So if a sysop has a BBS with a node 0 that
  687. // node is not counted.
  688.  
  689.     char PIn [30];
  690.  
  691.     SendMessage(PBBSWIN, WM_COMMAND, 10047, (LONG)(LPSTR) PIn);
  692.     return (asc_to_int (PIn));
  693. }
  694.  
  695. //--------------------------------------------------------------------------
  696. //
  697. // In order to send a message first call Init_Message with the header.
  698. // Then call Message_Line TOTAL_LINES Number of times.  Each with the
  699. // actual line of text for the message.
  700. // Then call Save_Message.
  701.  
  702. void Init_Message(HWND PBBSWIN,
  703.           LPSTR From,        // Person Sending Message 
  704.           LPSTR Tou,        // Message destination
  705.           LPSTR Topic,        // Subject of message
  706.           int Total_Lines,    // Total lines in message
  707.           int Forum_Num,    // Forum number to save in
  708.           BOOL Private)            // TRUE = Private message
  709. {          
  710.     char Pin [255];
  711.     wsprintf (Pin, "%s~%s~%s~%d~%d%c", From, Tou, Topic, Total_Lines,
  712.           Forum_Num, (Private ? 'Y' : 'N'));
  713.     
  714.     SendMessage(PBBSWIN, WM_COMMAND, 10050, (LPARAM)(LPSTR) Pin);
  715. }
  716.  
  717. void Message_Line(HWND PBBSWIN, LPSTR TheLine)
  718. {
  719.   SendMessage(PBBSWIN, WM_COMMAND, 10051, (LPARAM)(LPSTR) TheLine);
  720. }
  721.  
  722. void Save_Message(HWND PBBSWIN)
  723. {
  724.     SendMessage(PBBSWIN, WM_COMMAND, 10052, 0);
  725. }
  726.  
  727.  
  728. //---------------------------------------------------------------------------
  729. void Set_Node_Description(HWND PBBSWIN, LPSTR Doing)
  730. {
  731. // Sets the WHO IS ONLINE RECORD to what the user is doing.
  732. // Ex: Set_Node_Description(PBBSWIN, 'Using 3rd party door.');
  733.  
  734.     SendMessage(PBBSWIN, WM_COMMAND, 10053, (LPARAM)(LPSTR) Doing);
  735. }
  736.  
  737.  
  738. BOOL Is_User_Online(HWND PBBSWIN, LPSTR thename)
  739. {
  740. // Checks if THENAME is currently on-line as a user.  If THENAME is on-line
  741. //  returns TRUE 
  742.  
  743.     char pIn [255];
  744.  
  745.     lstrcpy (pIn, thename);
  746.     SendMessage(PBBSWIN, WM_COMMAND, 10054, (LPARAM)(LPSTR) pIn);
  747.     return (pIn[0] == 'Y');
  748. }
  749.  
  750.  
  751. // Common code for the DLL. This is just a demo and does not do anything
  752. // real useful. The common code is separate so that it can be called from
  753. // two different entry points, see below about POWERBBS_MAIN and
  754. // POWERBBS_PMAIN entry points.
  755.  
  756. void DoCode (HWND PBBSWin, LPSTR Stuff)
  757. {
  758.     
  759.     char            Inputs[255];
  760.     char            TBuff [255];
  761.     unsigned char        Counter;
  762.     LPPOWRUSER_RECORD        Puser;
  763.     LPPOWRUSER_RECORD_EXTENSION Fuser;
  764.     LPPOWER_CALLINFO_REC    Cuser;
  765.     LPPOWERBBS_FORUM_STRUCTURE    forum;
  766.     LPPBBSRECORD        bbs;
  767.     int                unum;
  768.     LPPOWRUSER_RECORD        Puser2;
  769.  
  770.  
  771.     if (lstrlen (Stuff))
  772.     {
  773.     Print_Modem(PBBSWin, "Parameter: ");
  774.     PrintLn_Modem(PBBSWin, Stuff);
  775.     }
  776.     ClearScreen(PBBSWin);
  777.     Write_ActLog(PBBSWin, "Entering Our Test .DLL!");
  778.     lstrcpy (Inputs, "|NAME|");
  779.     Convert_Macros(PBBSWin, Inputs);
  780.     Print_Modem(PBBSWin, "Welcome ");
  781.     PrintLn_Modem(PBBSWin, Inputs);
  782.     PrintLn_Modem(PBBSWin, "PowerDLL (c)1994 by Russell E. Frey");
  783.     PrintLn_Modem(PBBSWin, "This demo does NOTHING special, other than "
  784.           "TEST the capabilities of the DLL.");
  785.     PrintLn_Modem(PBBSWin, "");
  786.     Print_Modem(PBBSWin, "Run Demo? ");
  787.     if (! Get_YN(PBBSWin))
  788.     return;
  789.     
  790.     // Now Test Pause
  791.     
  792.     for (Counter = 0; Counter < 13; Counter ++)
  793.     {
  794.     PrintLn_Modem(PBBSWin, "This module is a DLL linked dynamically "
  795.               "to PowerBBS!");
  796.     PrintLn_Modem(PBBSWin, "Now easily write addons in Visual Basic, "
  797.               "C, C++, Pascal!");
  798.     
  799.     if (PauseStop(PBBSWin))
  800.         break;
  801.     if (No_User_Online(PBBSWin))
  802.         return;
  803.     }
  804.     Print_Modem(PBBSWin, "What do you like about this? ");
  805.     Ask_User(PBBSWin, Inputs, 20);
  806.     Print_Modem(PBBSWin, "You inputted [");
  807.     Print_Modem(PBBSWin, Inputs);
  808.     PrintLn_Modem(PBBSWin, "]");
  809.  
  810.     Print_Modem(PBBSWin, "Press ONE KEY:: ");
  811.     Inputs[0] = Get_Key(PBBSWin);
  812.     Back_Spaces(PBBSWin, 17);
  813.  
  814.     if (Get_YesNoQ(PBBSWin, "Did you like this program?", TRUE))
  815.     PrintLn_Modem(PBBSWin, "Thanks!");
  816.     else
  817.     PrintLn_Modem(PBBSWin, "Thats ok.  Oh BTW I just locked you out!");
  818.     Inputs [1] = '\0';
  819.     PrintLn_Modem(PBBSWin, Inputs);
  820.     Print_Modem(PBBSWin, "Press A B or C: ");
  821.     Inputs[0] = Get_Hot(PBBSWin, "ABC");
  822.     Inputs [1] = '\0';
  823.     PrintLn_Modem(PBBSWin, Inputs);
  824.     Type_File_To_Modem(PBBSWin, "C:\\Autoexec.Bat");
  825.     Print_Modem(PBBSWin, "Press ONE KEY (within two seconds):: ");
  826.     Inputs[0] = Input_Key_Time(PBBSWin, 2000);
  827.     Inputs [1] = '\0';
  828.     if ((unsigned char) Inputs[0] == (unsigned char) 0xFF)
  829.     PrintLn_Modem(PBBSWin, "TimeOut!");
  830.     else
  831.     PrintLn_Modem(PBBSWin, Inputs);
  832.     
  833.     Send_Modem_Command(PBBSWin, ">>");
  834. //    Execute_Prog(PBBSWin, "C:\\TEMP.BAT");
  835.     if (Key_Waiting(PBBSWin))
  836.     PrintLn_Modem(PBBSWin, "Key Waiting");
  837.     else
  838.     PrintLn_Modem(PBBSWin, "NO KEY WAITING");
  839.     
  840.     Change_Forum(PBBSWin, 3);
  841.     Run_Menu_Command(PBBSWin, 1);
  842. //    Run_PowerBase(PBBSWin, 1);
  843.     Print_Modem(PBBSWin, "Time Left: ");
  844.     unum = Time_Left(PBBSWin);
  845.     wsprintf (Inputs, "%d", unum);
  846.     PrintLn_Modem(PBBSWin, Inputs);
  847.  
  848.     Puser = Get_UserRec(PBBSWin);
  849.  
  850.     Print_Modem(PBBSWin, "Name = ");
  851.     PrintLn_Modem(PBBSWin, PackedToCString (Puser -> name, TBuff, 25));
  852.     Print_Modem(PBBSWin, "ZIP = ");
  853.     PrintLn_Modem(PBBSWin, PackedToCString (Puser -> zip, TBuff, 10));
  854.  
  855.     Fuser = Get_ForumUserRec(PBBSWin);
  856.     
  857.     if (Fuser -> Forum_Data[3].Options & 1)
  858.     PrintLn_Modem(PBBSWin, " You have access to forum #3!");
  859.     else
  860.     PrintLn_Modem(PBBSWin, " You do NOT have access to forum #3. <g>");
  861.  
  862.     Cuser = Get_CallInfo(PBBSWin);
  863.     Print_Modem(PBBSWin, "You are on at ");
  864.     Print_Modem(PBBSWin, PackedToCString (Cuser -> BaudRate, TBuff, 5));
  865.     PrintLn_Modem(PBBSWin, " bps! ");
  866.  
  867.     forum = Get_Current_ForumInfo(PBBSWin);
  868.     Print_Modem(PBBSWin, "Current Forum Name: ");
  869.     PrintLn_Modem(PBBSWin, PascalToCString (forum->forum_name_len, TBuff, 30));
  870.  
  871.     bbs = Get_BBS_Record(PBBSWin);
  872.     PrintLn_Modem(PBBSWin, "Opening File: ");
  873.     PrintLn_Modem(PBBSWin, PascalToCString (bbs -> OpeningLen, TBuff, 35));
  874.     if (Monitor_Mode(PBBSWin) == 'R')
  875.     PrintLn_Modem(PBBSWin, "Using RIP");
  876.     else if (Monitor_Mode(PBBSWin) == 'C')
  877.     PrintLn_Modem(PBBSWin, "Using ANSI");
  878.     else
  879.     PrintLn_Modem(PBBSWin, "Using ASCII");
  880.  
  881.     Print_Modem(PBBSWin, "Rec # of GF = ");
  882.     wsprintf (Inputs, "%d", Search_UserName(PBBSWin, "GLEN FREY"));
  883.     PrintLn_Modem(PBBSWin, Inputs);
  884.     
  885.     unum = Search_UserName(PBBSWin, "GLEN FREY");
  886.     
  887.     if (unum != 0)
  888.     {
  889.     HANDLE hTemp = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,
  890.                     (LONG) sizeof (POWRUSER_RECORD));
  891.     
  892. MessageBox (0, "Hm, found GLEN FREY!!!", "DEBUG", MB_OK);
  893.     
  894.     if (hTemp)
  895.     {
  896.         Puser2 = (LPPOWRUSER_RECORD) GlobalLock (hTemp);
  897.         if (Puser2)
  898.         {
  899.         Load_UserRec(PBBSWin, Puser2, unum);
  900.         Print_Modem(PBBSWin, "Password = ");
  901.         PrintLn_Modem(PBBSWin, PackedToCString (Puser2 -> Password,
  902.             TBuff, 11));
  903. //        Puser2^.Password[1] := 'N';
  904. //        Save_UserRec(PBBSWin, Puser2, unum);
  905.         GlobalUnlock (hTemp);
  906.         }
  907.         GlobalFree (hTemp);
  908.     }
  909.     }
  910.  
  911.     Init_Message(PBBSWin, "SYSOP", "TEST USER", "Thanks!", 2, 0, FALSE);
  912.     Message_Line(PBBSWin, "Hi Test User!");
  913.     Message_Line(PBBSWin, " ... The SysOp ");
  914.     Save_Message(PBBSWin);
  915.  
  916.     Set_Node_Description(PBBSWin, "In PowerDLL");
  917.     lstrcpy (Inputs, "|WHO-ON|");
  918.     Convert_Macros(PBBSWin, Inputs);
  919.  
  920.     if (Is_User_Online(PBBSWin, "GLEN FREY"))
  921.     PrintLn_Modem (PBBSWin, "Glen is On-Line!");
  922.     Print_Modem(PBBSWin, "Number Users Online: ");
  923.     wsprintf (Inputs, "%d", Number_Users_Online(PBBSWin));
  924.     PrintLn_Modem(PBBSWin, Inputs);
  925.     PrintLn_Modem(PBBSWin, "Exiting to PowerBBS...");
  926.     Get_Enter_Key(PBBSWin);
  927. //    End_Call(PBBSWin);
  928. }
  929.  
  930.  
  931. //-- Main DLL Module --
  932. //-- This procedure MUST be named as PowerBBS_Main.  PowerBBS assumes this
  933. //   procedure exists as this is the name that it calls when dynamically
  934. //   loading the DLL upon call from the BBS. ---
  935. // If the application is to be started from a PowerLanguage (.POW) program
  936. // you may also have an entry procedure that can take parameters. When
  937. // starting the DLL from PowerLanguage PowerBBS will check if the DLL has
  938. // an entry called POWERBBS_PMAIN and, if so, the PowerLanguage string
  939. // variables S1, S2, S3, S4 and S5 is passed in as far string pointers,
  940. // defined in windows as LPSTR. Even if, as in this example, only one
  941. // is used you MUST declare all five in the function, if not the DLL
  942. // may crash on exit.
  943. // If no POWERBBS_PMAIN is found or if called from a menu the normal
  944. // POWERBBS_MAIN function is called without any optional parameters.
  945. //
  946. // These two entry functions call a common function, the POWERBBS_MAIN
  947. // sends in a empty string while POWERBBS_PMAIN sends in the first
  948. // parameter S1 to the common function.
  949.  
  950. void _export WINAPI POWERBBS_MAIN (HWND PBBSWin)
  951. {
  952.     DoCode (PBBSWin, "");
  953. }
  954.  
  955. void _export WINAPI POWERBBS_PMAIN (HWND PBBSWin, LPSTR s1, LPSTR s2,
  956.                     LPSTR s3, LPSTR s4, LPSTR s5)
  957. {
  958.     DoCode (PBBSWin, s1);
  959. }
  960.