1 /*-------------------------------------------------------------------------
\r
3 * df32func extensions for Console Mode DataFlex 3.2
\r
5 * Copyright (c) 2007-2015, glyn@8kb.co.uk
\r
6 * Author: Glyn Astill <glyn@8kb.co.uk>
\r
8 *-------------------------------------------------------------------------
\r
11 #include <windows.h>
\r
14 #include <winsock.h>
\r
16 #include "gnuregex.h"
\r
17 #include "df32func.h"
\r
21 * http://msdn.microsoft.com/en-us/library/ms724253.aspx
\r
23 typedef struct _REG_TZI_FORMAT
\r
28 SYSTEMTIME StandardDate;
\r
29 SYSTEMTIME DaylightDate;
\r
32 SOCKET s, sc; /* Socket handle */
\r
35 * The number of cycles used by the processor since the start obtained on x86
\r
36 * processors (Intel, AMD), with the assembly command rdtsc.
\r
40 __asm__ __volatile__("rdtsc");
\r
44 * CLIENTSOCKET
\96 Creates a communication socket and connects to a remote host on the
\r
45 * supplied port and IP
\r
47 DLLIMPORT int ClientSocket(int PortNo, char* IPAddress){
\r
48 /* Start up Winsock */
\r
51 int error = WSAStartup(0x0202, &wsadata);
\r
53 /* Did something happen? */
\r
58 /* Did we get the right Winsock version? */
\r
59 if (wsadata.wVersion != 0x0202){
\r
60 WSACleanup(); /* Clean up Winsock */
\r
64 /* Fill out the information needed to initialize a socket */
\r
65 SOCKADDR_IN target; /* Socket address information */
\r
67 target.sin_family = AF_INET; /* address family Internet */
\r
68 target.sin_port = htons (PortNo); /* Port to connect on */
\r
69 target.sin_addr.s_addr = inet_addr (IPAddress); /* Target IP */
\r
71 s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); /* Create socket */
\r
72 if (s == INVALID_SOCKET){
\r
73 return -1; /* Couldn't create the socket */
\r
76 /* Try connecting */
\r
77 if (connect(s, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR){
\r
78 return -1; /* Couldn't connect */
\r
81 return s; /* Success - return our socket number */
\r
86 * SERVERSOCKET
\96 Creates a communication socket and a tcp server listening on a the
\r
87 * supplied port number
\r
89 DLLIMPORT int ServerSocket(int PortNo){
\r
90 /* Start up Winsock */
\r
93 int error = WSAStartup(0x0202, &wsadata);
\r
95 /* Did something happen? */
\r
100 /* Did we get the right Winsock version? */
\r
101 if (wsadata.wVersion != 0x0202){
\r
102 WSACleanup(); /* Clean up Winsock */
\r
106 /* Fill out the information needed to initialize a socket */
\r
107 SOCKADDR_IN target; /* Socket address information */
\r
109 target.sin_family = AF_INET; /* address family Internet */
\r
110 target.sin_port = htons (PortNo); /* Port to connect on */
\r
111 target.sin_addr.s_addr = INADDR_ANY; /* Target IP */
\r
113 s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); /* Create socket */
\r
114 if (s == INVALID_SOCKET){
\r
115 return -1; /* Couldn't create the socket */
\r
118 /* Try to bind to the socket */
\r
119 if (bind(s, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR) {
\r
120 return -1; /* Couldn't connect */
\r
123 /* Now we can start listening, We allow SOMNAXCONN connections. This will not return until we get a connection */
\r
124 if (listen(s, SOMAXCONN) == SOCKET_ERROR) {
\r
134 * CLOSECONNECTION
\96 shuts down a communication socket and closes any connection on it
\r
136 DLLIMPORT void CloseConnection (int socket){
\r
137 /* Close the socket if it exists */
\r
139 closesocket(socket);
\r
142 WSACleanup(); /* Clean up Winsock */
\r
146 * SEND - Send data over the communication socket
\r
148 DLLIMPORT int Send(int socket, char* data){
\r
149 return send(socket, data, strlen(data), 0);
\r
153 * RECEIVE - Recieve data over the client socket
\r
155 DLLIMPORT int Receive(int socket, char *pData){
\r
156 char data[255] = {0};
\r
159 memset(data, 0, sizeof(data));
\r
160 bytesIn = recv(socket, data, sizeof(data), 0);
\r
161 if (bytesIn == SOCKET_ERROR) {
\r
164 sprintf (pData, "%s", data );
\r
169 * ACCEPTCLIENT - Accept a client connection
\r
171 DLLIMPORT int AcceptClient(){
\r
172 SOCKADDR_IN client;
\r
173 int clientSize = sizeof(client);
\r
174 sc = accept(s, (SOCKADDR *)&client, &clientSize);
\r
175 if (sc == INVALID_SOCKET){
\r
182 * Generate a pseudo random integer from an integer
\r
184 DLLIMPORT unsigned int PseudoRand(unsigned int w){
\r
185 unsigned int m_w = w;
\r
186 unsigned int m_z = (w / 2);
\r
188 m_z = 36969 * (m_z & 65535) + (m_z >> 16);
\r
189 m_w = 18000 * (m_w & 65535) + (m_w >> 16);
\r
190 return (m_z << 16) + m_w; /* 32-bit result */
\r
194 * Generate a random integer from the cpu rdtsc
\r
196 DLLIMPORT unsigned int RdtscRand(){
\r
197 unsigned int n = 0;
\r
199 /* First digit must be non-zero: */
\r
205 for(i = 1; i < 8; i++)
\r
215 * Pull back timezone information from windows registry
\r
217 DLLIMPORT int GetTzi (TCHAR* zone, TCHAR *result)
\r
219 DWORD dwStatus, dwType, cbData;
\r
221 TCHAR szTime[128], szDate[128], szSubKey[256];
\r
223 REG_TZI_FORMAT tzi;
\r
225 /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms647490%28v=vs.85%29.aspx */
\r
226 lstrcpy(szSubKey, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\"));
\r
229 * https://msdn.microsoft.com/en-us/library/aa272954%28v=vs.60%29.aspx
\r
230 * https://msdn.microsoft.com/en-us/library/h1x0y282.aspx
\r
232 _tcscat(szSubKey, zone);
\r
234 dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey);
\r
235 if (dwStatus != NO_ERROR)
\r
236 return GetLastError();
\r
238 cbData = sizeof(REG_TZI_FORMAT);
\r
239 dwStatus = RegQueryValueEx (hKey, TEXT("TZI"), NULL, &dwType, (LPBYTE)&tzi, &cbData);
\r
240 if (dwStatus != NO_ERROR)
\r
241 return GetLastError();
\r
244 * tzi.StandardDate and tzi.DaylightDate are not a real SYSTEMTIME
\r
245 * but we should look at them to depict daylight saving
\r
246 * if month = 0 then not supported, year = 0 means every year.
\r
247 * http://msdn.microsoft.com/en-us/library/ms725481.asp
\r
250 _stprintf(result, "%d,%d,%d,%d/%d/%d/%d,%d:%d:%d,%d/%d/%d/%d,%d:%d:%d",
\r
251 tzi.Bias,tzi.StandardBias,tzi.DaylightBias,
\r
252 tzi.StandardDate.wYear,tzi.StandardDate.wMonth,tzi.StandardDate.wDay,tzi.StandardDate.wDayOfWeek,tzi.StandardDate.wHour,tzi.StandardDate.wMinute,tzi.StandardDate.wSecond,
\r
253 tzi.DaylightDate.wYear,tzi.DaylightDate.wMonth,tzi.DaylightDate.wDay,tzi.DaylightDate.wDayOfWeek,tzi.DaylightDate.wHour,tzi.DaylightDate.wMinute,tzi.DaylightDate.wSecond
\r
260 * Check for a regex match
\r
262 DLLIMPORT int RegexpMatch (const char *str, const char *pattern, const char *flags, int errors)
\r
264 return regexp_match(str, pattern, flags, errors);
\r
268 * Return all matches in the regex as a string and return in custom format
\r
270 DLLIMPORT int RegexpMatches(const char *str, const char *pattern, const char *flags, char *output, int output_len, int errors)
\r
272 char *matches = regexp_matches(str, pattern, flags, errors);
\r
276 if (matches != NULL)
\r
278 matches_len = strlen(matches);
\r
279 if (matches_len <= output_len)
\r
281 strncpy(output, matches, matches_len);
\r
296 * Substitutes matches with the regex pattern in the string with the replacement
\r
299 DLLIMPORT int RegexpReplace(const char *str, const char *pattern, const char *replacement, const char *flags, char *output, int output_len, int errors)
\r
301 char *replaced = regexp_replace(str, pattern, replacement, flags, errors);
\r
305 if (replaced != NULL)
\r
307 replaced_len = strlen(replaced);
\r
309 if (replaced_len <= output_len)
\r
311 strncpy(output, replaced, replaced_len);
\r
330 BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
\r
331 DWORD reason /* Reason this function is being called. */ ,
\r
332 LPVOID reserved /* Not used. */ )
\r
336 case DLL_PROCESS_ATTACH:
\r
339 case DLL_PROCESS_DETACH:
\r
342 case DLL_THREAD_ATTACH:
\r
345 case DLL_THREAD_DETACH:
\r
349 /* Returns TRUE on success, FALSE on failure */
\r