View | Details | Raw Unified | Return to bug 19953 | Differences between
and this patch

Collapse All | Expand All

(-)xrdp/xrdp-0.5.0~20100303cvs.orig/.bzrignore (+2 lines)
Line 0    Link Here 
1
RE:.*CVS
2
RE:.*CVS/.*
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/arch.h (-6 / +10 lines)
 Lines 1-5    Link Here 
1
/*
1
/*
2
   Copyright (c) 2004-2010 Jay Sorg
2
   Copyright (c) 2004-2009 Jay Sorg
3
3
4
   Permission is hereby granted, free of charge, to any person obtaining a
4
   Permission is hereby granted, free of charge, to any person obtaining a
5
   copy of this software and associated documentation files (the "Software"),
5
   copy of this software and associated documentation files (the "Software"),
 Lines 24-44    Link Here 
24
#if !defined(ARCH_H)
24
#if !defined(ARCH_H)
25
#define ARCH_H
25
#define ARCH_H
26
26
27
#if !(defined(L_ENDIAN) || defined(B_ENDIAN))
28
/* check endianess */
27
/* check endianess */
29
#if defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || \
28
#if defined(__sparc__) || defined(__PPC__) || defined(__ppc__)
30
    defined(__hppa__)
31
#define B_ENDIAN
29
#define B_ENDIAN
30
#elif defined(__BYTE_ORDER)
31
#if __BYTE_ORDER == __LITTLE_ENDIAN
32
#define L_ENDIAN
33
#elif __BYTE_ORDER == __BIG_ENDIAN
34
#define B_ENDIAN
35
#endif
32
#else
36
#else
33
#define L_ENDIAN
37
#define L_ENDIAN
34
#endif
38
#endif
39
35
/* check if we need to align data */
40
/* check if we need to align data */
36
#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \
41
#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \
37
    defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
42
    defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
38
    defined(__ia64__) || defined(__ppc__) || defined(__arm__)
43
    defined(__ia64__) || defined(__ppc__)
39
#define NEED_ALIGN
44
#define NEED_ALIGN
40
#endif
45
#endif
41
#endif
42
46
43
/* defines for thread creation factory functions */
47
/* defines for thread creation factory functions */
44
#if defined(_WIN32)
48
#if defined(_WIN32)
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/crc32.c (+100 lines)
Line 0    Link Here 
1
/*----------------------------------------------------------------------------*\
2
 *  CRC-32 version 2.0.0RDP created 2010-03-15, based on
3
 *    CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
4
 *
5
 *  This function generates the CRC-32 values for the files named in the
6
 *  command-line arguments.  These are the same CRC-32 values used by GZIP,
7
 *  PKZIP, and ZMODEM.  The Crc32_ComputeBuf() can also be detached and
8
 *  used independently.
9
 *
10
 *  Based on the byte-oriented implementation "File Verification Using CRC"
11
 *  by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
12
 *
13
 *  v1.0.0:	original release.
14
 *  v1.0.1:	fixed printf formats.
15
 *  v1.0.2:	fixed something else.
16
 *  v1.0.3:	replaced CRC constant table by generator function.
17
 *  v1.0.4:	reformatted code, made ANSI C.  1994-12-05.
18
 *  v2.0.0:	rewrote to use memory buffer & static table, 2006-04-29.
19
 *  v2.0.0RDP:	modified for use in xrdp by Ryan Rafferty, 2010-03-15.
20
\*----------------------------------------------------------------------------*/
21
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <stdint.h>
25
26
#include "crc32.h"
27
28
/*----------------------------------------------------------------------------*\
29
 *  NAME:
30
 *     Crc32_ComputeBuf() - computes the CRC-32 value of a memory buffer
31
 *  DESCRIPTION:
32
 *     Computes or accumulates the CRC-32 value for a memory buffer.
33
 *     The 'inCrc32' gives a previously accumulated CRC-32 value to allow
34
 *     a CRC to be generated for multiple sequential buffer-fuls of data.
35
 *     The 'inCrc32' for the first buffer must be zero.
36
 *  ARGUMENTS:
37
 *     inCrc32 - accumulated CRC-32 value, must be 0 on first call
38
 *     buf     - buffer to compute CRC-32 value for
39
 *     bufLen  - number of bytes in buffer
40
 *  RETURNS:
41
 *     crc32 - computed CRC-32 value
42
 *  ERRORS:
43
 *     (no errors are possible)
44
\*----------------------------------------------------------------------------*/
45
46
uint32_t Crc32_ComputeBuf( uint32_t inCrc32, const void * buf, size_t bufLen ) {
47
  static const uint32_t crcTable[256] = {
48
   0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,
49
   0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,
50
   0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,
51
   0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,
52
   0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,
53
   0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
54
   0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC,
55
   0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,
56
   0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,
57
   0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,
58
   0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,
59
   0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
60
   0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,
61
   0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE,
62
   0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,
63
   0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
64
   0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,
65
   0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
66
   0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,
67
   0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,
68
   0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268,
69
   0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,
70
   0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,
71
   0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
72
   0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,
73
   0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,
74
   0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,
75
   0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,
76
   0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,
77
   0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
78
   0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,
79
   0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
80
   0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,
81
   0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,
82
   0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,
83
   0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
84
   0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D };
85
  uint32_t crc32 = 0;
86
  size_t i = 0;
87
  uint8_t * byteBuf = (uint8_t *)NULL;
88
89
  /** accumulate crc32 for buffer **/
90
  byteBuf = (uint8_t *)buf;
91
  crc32 = inCrc32 ^ 0xFFFFFFFF;
92
  for (i = 0; i < bufLen; i++) {
93
    crc32 = (crc32 >> 8) ^ (crcTable[ ((crc32 ^ byteBuf[i]) & 0xFF) ]);
94
  }
95
  return( crc32 ^ 0xFFFFFFFF );
96
}
97
98
/*----------------------------------------------------------------------------*\
99
 *  END OF MODULE: crc32.c
100
\*----------------------------------------------------------------------------*/
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/crc32.h (+19 lines)
Line 0    Link Here 
1
#ifndef __RDP_CRC32__
2
#define __RDP_CRC32__
3
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <stdint.h>
7
8
9
/*----------------------------------------------------------------------------*\
10
 *  Function prototypes
11
\*----------------------------------------------------------------------------*/
12
13
uint32_t Crc32_ComputeBuf( uint32_t inCrc32, const void * buf, size_t bufLen );
14
15
/*----------------------------------------------------------------------------*\
16
 *  End of crc32.h
17
\*----------------------------------------------------------------------------*/
18
19
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/dbg.c (+40 lines)
Line 0    Link Here 
1
#include "dbg.h"
2
#include "thread_calls.h"
3
#include "thread_macros.h"
4
5
static tc_t g_tc_mutex; // = TC_MUTEX_INITIALIZER;
6
static tc_p mutex_tc = (tc_p)(&g_tc_mutex);
7
static unsigned int taskq_count = 0;
8
9
void DBGLOG(const char * _itype, const char * _itxt) {
10
  char taskq_text[256];
11
  FILE * taskq = NULL;
12
  const char * deflt = "/tmp/taskq.log";
13
14
  snprintf(taskq_text,255,"%s",deflt);
15
  if (_itype != NULL && (unsigned int)_itype > 100) {
16
    if (strlen(_itype) > 0) {
17
      snprintf(taskq_text,255,"%s%s%s","/tmp/taskq_",_itype,".log");
18
    }
19
  }
20
21
  if (!strcmp(_itype,"drdynvc") || !strcmp(_itype,"trans") || !strcmp(_itype,"rdpport") || !strcmp(_itype,"rdpfs") || !strcmp(_itype,"port") || !strcmp(_itype,"child") || !strcmp(_itype,"parent") || !strcmp(_itype,"xrdp") || !strcmp(_itype,"sound") || !strcmp(_itype,"rdprec") || !strcmp(_itype,"chansrv") || !strcmp(_itype,"clipboard") || !strcmp(_itype,"net") || !strcmp(_itype,"sesman") || !strcmp(_itype,"redir") || !strncmp(_itype,"libscp",strlen("libscp")))
22
  {
23
   taskq = fopen(taskq_text,"a");
24
   if (taskq!=NULL) {
25
26
    TC_MUTEX_LOCK(mutex_tc);
27
28
    if (taskq_count==0) {
29
      fprintf(taskq,"\n*********\n");
30
    }
31
    fprintf(taskq," (%d) ",taskq_count);
32
    fprintf(taskq,"%s\n",_itxt);
33
    taskq_count++;
34
35
    TC_MUTEX_UNLOCK(mutex_tc);
36
37
    fclose(taskq);
38
   }
39
  }
40
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/dbg.h (+46 lines)
Line 0    Link Here 
1
#ifndef __taskq__
2
#define __taskq__
3
4
#include <stdio.h>
5
#include <string.h>
6
#include <time.h>
7
#include <langinfo.h>
8
9
#define DBGTIMESTRING	"(%s, %s %d, %d:%.2d)"
10
11
#define MDBGLOG(dest, ...) {									\
12
  time_t mdbglog_rawtime;									\
13
  struct tm * mdbglog_tm;									\
14
  char mdbglog_mtbuf[512];									\
15
  char mdbglog_tbuf[512];									\
16
  char mdbglog_rbuf[512];									\
17
  char mdbglog_datebuf[256];									\
18
  g_memset(&mdbglog_rawtime, 0x00, sizeof(time_t));						\
19
  g_memset(mdbglog_mtbuf, 0x00, sizeof(mdbglog_mtbuf));						\
20
  g_memset(mdbglog_tbuf, 0x00, sizeof(mdbglog_tbuf));						\
21
  g_memset(mdbglog_rbuf, 0x00, sizeof(mdbglog_rbuf));						\
22
  g_memset(mdbglog_datebuf, 0x00, sizeof(mdbglog_datebuf));					\
23
  mdbglog_rawtime = g_time(0);									\
24
  mdbglog_tm = localtime(&mdbglog_rawtime);							\
25
  if (mdbglog_tm != NULL) {									\
26
    /* strftime(mdbglog_datebuf, sizeof(mdbglog_datebuf), nl_langinfo (D_T_FMT), mdbglog_tm); */	\
27
    g_snprintf(mdbglog_mtbuf,sizeof(mdbglog_mtbuf), __VA_ARGS__);				\
28
    /* g_snprintf(mdbglog_tbuf,sizeof(mdbglog_tbuf),"%s",mdbglog_datebuf); */				\
29
    /* g_snprintf(mdbglog_rbuf,sizeof(mdbglog_rbuf),"%s %s",mdbglog_tbuf,mdbglog_mtbuf); */		\
30
    /* g_snprintf(mdbglog_rbuf,sizeof(mdbglog_rbuf),"%s",mdbglog_mtbuf); */		\
31
    DBGLOG(dest,mdbglog_mtbuf);									\
32
  }												\
33
}
34
35
#define VLOG(...) MDBGLOG("vnc", __VA_ARGS__)
36
#define NLOG(...) MDBGLOG("net", __VA_ARGS__)
37
#define SLOG(...) MDBGLOG("sound", __VA_ARGS__)
38
#define CLOG(...) MDBGLOG("chansrv", __VA_ARGS__)
39
#define DLOG(...) MDBGLOG("devredir", __VA_ARGS__)
40
41
//unsigned int taskq_count;
42
/* char mtbuf[512];	*/
43
44
void DBGLOG(const char *, const char *);
45
46
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/defines.h (-7 / +67 lines)
 Lines 20-28    Link Here 
20
20
21
*/
21
*/
22
22
23
#if !defined(DEFINES_H)
23
#ifndef DEFINES_H
24
#define DEFINES_H
24
#define DEFINES_H
25
25
26
#define HAVE_PULSE_AUDIO
27
#define _XRDP_ENABLE_I18N_
28
26
/* check for debug */
29
/* check for debug */
27
#ifdef XRDP_DEBUG
30
#ifdef XRDP_DEBUG
28
#define DEBUG(args) g_writeln args;
31
#define DEBUG(args) g_writeln args;
 Lines 48-59    Link Here 
48
#define RECTOFFSET(r, dx, dy) \
51
#define RECTOFFSET(r, dx, dy) \
49
{ (r).left += dx; (r).top += dy; (r).right += dx; (r).bottom += dy; }
52
{ (r).left += dx; (r).top += dy; (r).right += dx; (r).bottom += dy; }
50
#define GETPIXEL8(d, x, y, w) (*(((unsigned char*)d) + ((y) * (w) + (x))))
53
#define GETPIXEL8(d, x, y, w) (*(((unsigned char*)d) + ((y) * (w) + (x))))
54
#define GETPIXEL15(d, x, y, w) (*(((unsigned short*)d) + ((y) * (w) + (x))))
51
#define GETPIXEL16(d, x, y, w) (*(((unsigned short*)d) + ((y) * (w) + (x))))
55
#define GETPIXEL16(d, x, y, w) (*(((unsigned short*)d) + ((y) * (w) + (x))))
56
#define GETPIXEL24(d, x, y, w) (*(((unsigned int*)d) + ((y) * (w) + (x))))
52
#define GETPIXEL32(d, x, y, w) (*(((unsigned int*)d) + ((y) * (w) + (x))))
57
#define GETPIXEL32(d, x, y, w) (*(((unsigned int*)d) + ((y) * (w) + (x))))
53
#define SETPIXEL8(d, x, y, w, v) \
58
#define SETPIXEL8(d, x, y, w, v) \
54
(*(((unsigned char*)d) + ((y) * (w) + (x))) = (v))
59
(*(((unsigned char*)d) + ((y) * (w) + (x))) = (v))
60
#define SETPIXEL15(d, x, y, w, v) \
61
(*(((unsigned short*)d) + ((y) * (w) + (x))) = (v))
55
#define SETPIXEL16(d, x, y, w, v) \
62
#define SETPIXEL16(d, x, y, w, v) \
56
(*(((unsigned short*)d) + ((y) * (w) + (x))) = (v))
63
(*(((unsigned short*)d) + ((y) * (w) + (x))) = (v))
64
#define SETPIXEL24(d, x, y, w, v) \
65
(*(((unsigned int*)d) + ((y) * (w) + (x))) = (v))
57
#define SETPIXEL32(d, x, y, w, v) \
66
#define SETPIXEL32(d, x, y, w, v) \
58
(*(((unsigned int*)d) + ((y) * (w) + (x))) = (v))
67
(*(((unsigned int*)d) + ((y) * (w) + (x))) = (v))
59
#define COLOR8(r, g, b) \
68
#define COLOR8(r, g, b) \
 Lines 66-82    Link Here 
66
#define COLOR16(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
75
#define COLOR16(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
67
#define COLOR24RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
76
#define COLOR24RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
68
#define COLOR24BGR(r, g, b) (((b) << 16) | ((g) << 8) | (r))
77
#define COLOR24BGR(r, g, b) (((b) << 16) | ((g) << 8) | (r))
78
#define COLOR32RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
79
#define COLOR32BGR(r, g, b) (((b) << 24) | ((g) << 16) | ((r) << 8))
69
#define SPLITCOLOR15(r, g, b, c) \
80
#define SPLITCOLOR15(r, g, b, c) \
70
{ \
81
{ \
71
  r = (((c) >> 7) & 0xf8) | (((c) >> 12) & 0x7); \
82
    r = c & 0x7C00;	\
72
  g = (((c) >> 2) & 0xf8) | (((c) >>  8) & 0x7); \
83
    g = c & 0x3E00;	\
73
  b = (((c) << 3) & 0xf8) | (((c) >>  2) & 0x7); \
84
    b = c & 0x001F;	\
74
}
85
}
75
#define SPLITCOLOR16(r, g, b, c) \
86
#define SPLITCOLOR16(r, g, b, c) \
76
{ \
87
{ \
77
  r = (((c) >> 8) & 0xf8) | (((c) >> 13) & 0x7); \
88
    r = c & 0xF800;	\
78
  g = (((c) >> 3) & 0xfc) | (((c) >>  9) & 0x3); \
89
    g = c & 0x07E0;	\
79
  b = (((c) << 3) & 0xf8) | (((c) >>  2) & 0x7); \
90
    b = c & 0x001F;	\
80
}
91
}
81
#define SPLITCOLOR32(r, g, b, c) \
92
#define SPLITCOLOR32(r, g, b, c) \
82
{ \
93
{ \
 Lines 91-93    Link Here 
91
#define USE_CRC
102
#define USE_CRC
92
103
93
#endif
104
#endif
105
106
#ifndef __G_MACROS_H__
107
#ifndef __XRDP_G_MACROS__
108
#define __XRDP_G_MACROS__
109
110
/*
111
  * The G_LIKELY and G_UNLIKELY macros let the programmer give hints to 
112
  * the compiler about the expected result of an expression. Some compilers
113
  * can use this information for optimizations.
114
  *
115
  * The _G_BOOLEAN_EXPR macro is intended to trigger a gcc warning when
116
  * putting assignments in g_return_if_fail ().  
117
  */
118
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
119
#define _G_BOOLEAN_EXPR(expr)                   \
120
__extension__ ({                               \
121
int _g_boolean_var_;                         \
122
if (expr)                                    \
123
_g_boolean_var_ = 1;                      \
124
else                                         \
125
_g_boolean_var_ = 0;                      \
126
_g_boolean_var_;                             \
127
})
128
#define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 1))
129
#define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 0))
130
#else
131
#define G_LIKELY(expr) (expr)
132
#define G_UNLIKELY(expr) (expr)
133
#endif
134
 
135
#endif /* __XRDP_G_MACROS__ */
136
#endif /* __G_MACROS_H__ */
137
138
139
#ifndef __XRDP_STREAMS_DEFS__
140
#define __XRDP_STREAMS_DEFS__
141
142
#define MAX_STREAM			65528
143
/* #define MAX_STREAM			8192	*/
144
#define MAX_PDU_LENGTH_TOTAL		65528
145
#define MAX_PDU_LENGTH_OLD		(MAX_STREAM - 32)
146
#define MAX_PDU_LENGTH			((MAX_STREAM / 2) - 32)
147
148
#define WO_UNSPEC		0
149
#define WO_INET			1
150
#define WO_LOCAL		2
151
#define WO_FIFO			3
152
153
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/devredir_defs.h (+1504 lines)
Line 0    Link Here 
1
2
#ifndef __XRDP_DEVREDIR_DEFS_H__
3
#define __XRDP_DEVREDIR_DEFS_H__
4
5
#include <stdint.h>
6
#include "defines.h"
7
#include "ntstatus.h"
8
#include "arch.h"
9
#include "parse.h"
10
#include "sound_defs.h"
11
#include "trans.h"
12
#include "thread_calls.h"
13
14
#ifndef BYTE
15
#define BYTE		uint8_t
16
#endif
17
#ifndef WORD
18
#define WORD		uint16_t
19
#endif
20
#ifndef DWORD
21
#define DWORD		uint32_t
22
#endif
23
#ifndef QWORD
24
#define QWORD		uint64_t
25
#endif
26
27
#ifndef RDPDR_DTYP_SERIAL
28
#define RDPDR_DTYP_SERIAL	0x00000001
29
#endif
30
#ifndef RDPDR_DTYP_PARALLEL
31
#define RDPDR_DTYP_PARALLEL	0x00000002
32
#endif
33
#ifndef RDPDR_DTYP_PRINT
34
#define RDPDR_DTYP_PRINT	0x00000004
35
#endif
36
#ifndef RDPDR_DTYP_FILESYSTEM
37
#define RDPDR_DTYP_FILESYSTEM	0x00000008
38
#endif
39
#ifndef RDPDR_DTYP_SMARTCARD
40
#define RDPDR_DTYP_SMARTCARD	0x00000020
41
#endif
42
43
typedef union _NTSTATUS {
44
	DWORD			Value;
45
	struct _Fields {
46
	  unsigned int	Sev:2;
47
	  unsigned int	C:1;
48
	  unsigned int	N:1;
49
	  unsigned int	Facility:12;
50
	  WORD		Code;
51
	}			Fields;
52
53
} NTSTATUS;
54
55
typedef struct _callback {
56
57
	int		callback_index;
58
	int		FileId;
59
	int		length;
60
	void *		data;
61
62
	int		opid;		/* the opid assigned by "get_opid()" */
63
	struct _rdpfs *	fs;		/* pointer to the filesystem to which the original operation pertains */
64
	struct _rdpport * port;		/* pointer to the port to which the original operation pertains */
65
	struct _rdpprint * printer;	/* pointer to the printer to which the original operation pertains */
66
	struct _rdpsc *	smartcard;	/* pointer to the smartcard to which the original operation pertains */
67
	unsigned int	device_id;
68
	int		type;		/* 0 = fd; 1  = trans */
69
	tbus		fd;		/* file descriptor over which to send reply */
70
	struct trans *	trans;		/* trans channel (to be used instead of "fd" if type == 1) */
71
	DWORD		CompletionId;	/* the CompletionId of the RDP request corresponding to the original operation */
72
	DWORD		opcode;		/* the rdpfs (or rdpport, rdpprinter, rdpsc) opcode of the original operation */
73
//	int		length;		/* length of "userdata", in bytes */
74
//	int		FileId;		/* file handle specified by the client */
75
	int		uniqid;		/* specified by the filesystem handler per transaction */
76
	NTSTATUS	IoStatus;	/* indicates success or error code returned by the filesystem operation, if any */
77
	int		buflen;		/* size (in bytes) of the reply data buffer */
78
	uint32_t	flags;
79
	uint8_t		cmd;
80
	uint32_t	mask;
81
	char		fname[512];
82
	uint64_t	actime;
83
	uint64_t	modtime;
84
	tc_t		mutex;
85
	tc_t		cv;
86
//	pthread_mutex_t	mutex;
87
//	pthread_cond_t	cv;
88
89
	#define	RDPFS_CB_MAGIC	0xcdbea459
90
	uint32_t	magic;
91
92
	int		seq;
93
	int		idx;
94
	int		val;
95
	
96
97
	/* a pointer to the actual function to be called: */
98
	void		(*func)(void *, int, tbus, struct trans *, DWORD, DWORD, int, BYTE *);
99
	int		(*setData)(struct _callback *, int, const BYTE *);
100
	int		(*setFunc)(struct _callback *, void (*)(void *, int, tbus, struct trans *, DWORD, DWORD, int, BYTE *));
101
//	int		(*call)(struct _callback *);
102
	void *		(*call)(void *);
103
	int		(*callData)(struct _callback *, int, const BYTE *);
104
105
	BYTE *		userdata;	/* optional extra data */
106
107
	#define	CBFLAG_NONE		0x00000000	/* no flags are set */
108
	#define	CBFLAG_FINAL		0x00000001	/* the reply corresponds to the final (or only) step in a series */
109
	#define CBFLAG_INTERMEDIATE	0x00000002	/* the reply corresponds to an intermediate step in a series (rather than the final step) */
110
	#define	CBFLAG_USERDATA		0x00000004	/* the userdata buffer contains data */
111
	#define	CBFLAG_IOSTATUS		0x00000008	/* the IoStatus field is set */
112
	#define	CBFLAG_FUNC		0x00000010	/* the "func" field points to a valid callback function that should be invoked */
113
	#define	CBFLAG_IRQ		0x00000020	/* the current step is part of a pseudo-interrupt routine */
114
	#define	CBFLAG_MUTEX		0x00000040	/* the mutex field should be handled appropriately */
115
	#define	CBFLAG_SUPPRESS		0x00000080	/* do not transmit a reply message */
116
	#define	CBFLAG_CMD		0x00000100	/* the cmd field indicates the IOCTL command */
117
	#define	CBFLAG_MASK		0x00000200	/* the mask field contains a bitmask */
118
	#define	CBFLAG_FS		0x01000000	/* the reply corresponds to a redirected filesystem operation */
119
	#define	CBFLAG_PORT		0x02000000	/* the reply corresponds to a redirected serial port or paralle port operation */
120
	#define	CBFLAG_SC		0x04000000	/* the reply corresponds to a redirected smartcard operation */
121
	#define	CBFLAG_PRINT		0x08000000	/* the reply corresponds to a redirected printer operation */
122
} callback;
123
124
/*****************************************************************************/
125
typedef uint64_t FILE_ALLOCATION_INFORMATION;
126
127
typedef struct _RDP_FILE_RENAME_INFORMATION {
128
	BYTE					ReplaceIfExists;
129
	BYTE					RootDirectory;
130
	DWORD					FileNameLength;
131
	BYTE *					FileName;
132
} RDP_FILE_RENAME_INFORMATION;
133
134
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
135
	DWORD					FileSystemAttributes;
136
	DWORD					MaximumComponentNameLength;
137
	DWORD					FileSystemNameLength;
138
	BYTE					FileSystemName[512];
139
140
	#define	FILE_SUPPORTS_TRANSACTIONS	0x00200000
141
	#define	FILE_SEQUENTIAL_WRITE_ONCE	0x00100000
142
	#define	FILE_READ_ONLY_VOLUME		0x00080000
143
	#define	FILE_NAMED_STREAMS		0x00040000
144
	#define	FILE_SUPPORTS_ENCRYPTION	0x00020000
145
	#define	FILE_SUPPORTS_OBJECT_IDS	0x00010000
146
	#define	FILE_VOLUME_IS_COMPRESSED	0x00008000
147
	#define	FILE_SUPPORTS_REMOTE_STORAGE	0x00000100
148
	#define	FILE_SUPPORTS_REPARSE_POINTS	0x00000080
149
	#define	FILE_SUPPORTS_SPARSE_FILES	0x00000040
150
	#define	FILE_VOLUME_QUOTAS		0x00000020
151
	#define	FILE_FILE_COMPRESSION		0x00000010
152
	#define	FILE_PERSISTENT_ACLS		0x00000008
153
	#define	FILE_UNICODE_ON_DISK		0x00000004
154
	#define	FILE_CASE_PRESERVED_NAMES	0x00000002
155
	#define	FILE_CASE_SENSITIVE_SEARCH	0x00000001
156
} FILE_FS_ATTRIBUTE_INFORMATION;
157
158
typedef struct _FILE_FS_CONTROL_INFORMATION {
159
	QWORD					FreeSpaceStartFiltering;
160
	QWORD					FreeSpaceThreshold;
161
	QWORD					FreeSpaceStopFiltering;
162
	QWORD					DefaultQuotaThreshold;
163
	QWORD					DefaultQuotaLimit;
164
	DWORD					FileSystemControlFlags;
165
166
	#define	FILE_VC_CONTENT_INDEX_DISABLED	0x00000008
167
	#define	FILE_VC_LOG_QUOTA_LIMIT		0x00000020
168
	#define	FILE_VC_LOG_QUOTA_THRESHOLD	0x00000010
169
	#define	FILE_VC_LOG_VOLUME_LIMIT	0x00000080
170
	#define	FILE_VC_LOG_VOLUME_THRESHOLD	0x00000040
171
	#define	FILE_VC_QUOTA_ENFORCE		0x00000002
172
	#define	FILE_VC_QUOTA_TRACK		0x00000001
173
	#define	FILE_VC_QUOTAS_INCOMPLETE	0x00000100
174
	#define	FILE_VC_QUOTAS_REBUILDING	0x00000200
175
} FILE_FS_CONTROL_INFORMATION;
176
177
typedef struct _FILE_FS_LABEL_INFORMATION {
178
	DWORD					VolumeLabelLength;
179
	BYTE *					VolumeLabel;
180
} FILE_FS_LABEL_INFORMATION;
181
182
typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
183
	QWORD					TotalAllocationUnits;
184
	QWORD					CallerAvailableAllocationUnits;
185
	QWORD					ActualAvailableAllocationUnits;
186
	DWORD					SectorsPerAllocationUnit;
187
	DWORD					BytesPerSector;
188
} FILE_FS_FULL_SIZE_INFORMATION;
189
190
typedef struct _FILE_FS_SIZE_INFORMATION {
191
	QWORD					TotalAllocationUnits;
192
	QWORD					ActualAvailableAllocationUnits;
193
	DWORD					SectorsPerAllocationUnit;
194
	DWORD					BytesPerSector;
195
} FILE_FS_SIZE_INFORMATION;
196
197
typedef struct _FILE_FS_DEVICE_INFORMATION {
198
	DWORD						DeviceType;
199
	DWORD						Characteristics;
200
201
	#define	FILE_REMOVABLE_MEDIA			0x00000001
202
	#define	FILE_READ_ONLY_DEVICE			0x00000002
203
	#define	FILE_FLOPPY_DISKETTE			0x00000004
204
	#define	FILE_WRITE_ONCE_MEDIA			0x00000008
205
	#define	FILE_REMOTE_DEVICE			0x00000010
206
	#define	FILE_DEVICE_IS_MOUNTED			0x00000020
207
	#define	FILE_VIRTUAL_VOLUME			0x00000040
208
	#define	FILE_AUTOGENERATED_DEVICE_NAME		0x00000080
209
	#define	FILE_DEVICE_SECURE_OPEN			0x00000100
210
	#define	FILE_CHARACTERISTIC_PNP_DEVICE		0x00000800
211
	#define	FILE_CHARACTERISTIC_TS_DEVICE		0x00001000
212
	#define	FILE_CHARACTERISTIC_WEBDAV_DEVICE	0x00002000
213
214
        #define	FILE_DEVICE_BEEP			0x00000001
215
	#define	FILE_DEVICE_CD_ROM			0x00000002
216
        #define	FILE_DEVICE_CD_ROM_FILE_SYSTEM		0x00000003
217
        #define	FILE_DEVICE_CONTROLLER			0x00000004
218
        #define	FILE_DEVICE_DATALINK			0x00000005
219
        #define	FILE_DEVICE_DFS				0x00000006
220
	#define	FILE_DEVICE_DISK			0x00000007
221
        #define	FILE_DEVICE_DISK_FILE_SYSTEM		0x00000008
222
        #define	FILE_DEVICE_FILE_SYSTEM			0x00000009
223
        #define	FILE_DEVICE_INPORT_PORT			0x0000000a
224
        #define	FILE_DEVICE_KEYBOARD         	  0x0000000b
225
        #define	FILE_DEVICE_MAILSLOT         	  0x0000000c
226
        #define	FILE_DEVICE_MIDI_IN          	  0x0000000d
227
        #define	FILE_DEVICE_MIDI_OUT         	  0x0000000e
228
        #define	FILE_DEVICE_MOUSE            	  0x0000000f
229
        #define	FILE_DEVICE_MULTI_UNC_PROVIDER  0x00000010
230
        #define	FILE_DEVICE_NAMED_PIPE			0x00000011
231
        #define	FILE_DEVICE_NETWORK          	  0x00000012
232
        #define	FILE_DEVICE_NETWORK_BROWSER  	  0x00000013
233
        #define	FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
234
        #define	FILE_DEVICE_NULL             	  0x00000015
235
        #define	FILE_DEVICE_PARALLEL_PORT    	  0x00000016
236
        #define	FILE_DEVICE_PHYSICAL_NETCARD 	  0x00000017
237
        #define	FILE_DEVICE_PRINTER          	  0x00000018
238
        #define	FILE_DEVICE_SCANNER          	  0x00000019
239
        #define	FILE_DEVICE_SERIAL_MOUSE_PORT   0x0000001a
240
        #define	FILE_DEVICE_SERIAL_PORT      	  0x0000001b
241
        #define	FILE_DEVICE_SCREEN           	  0x0000001c
242
        #define	FILE_DEVICE_SOUND            	  0x0000001d
243
        #define	FILE_DEVICE_STREAMS          	  0x0000001e
244
        #define	FILE_DEVICE_TAPE             	  0x0000001f
245
        #define	FILE_DEVICE_TAPE_FILE_SYSTEM 	  0x00000020
246
        #define	FILE_DEVICE_TRANSPORT        	  0x00000021
247
        #define	FILE_DEVICE_UNKNOWN          	  0x00000022
248
        #define	FILE_DEVICE_VIDEO            	  0x00000023
249
        #define	FILE_DEVICE_VIRTUAL_DISK     	  0x00000024
250
        #define	FILE_DEVICE_WAVE_IN          	  0x00000025
251
        #define	FILE_DEVICE_WAVE_OUT         	  0x00000026
252
        #define	FILE_DEVICE_8042_PORT        	  0x00000027
253
        #define	FILE_DEVICE_NETWORK_REDIRECTOR  0x00000028
254
        #define	FILE_DEVICE_BATTERY          	  0x00000029
255
        #define	FILE_DEVICE_BUS_EXTENDER     	  0x0000002a
256
        #define	FILE_DEVICE_MODEM            	  0x0000002b
257
        #define	FILE_DEVICE_VDM              	  0x0000002c
258
        #define FILE_DEVICE_MASS_STORAGE        0x0000002d
259
        #define FILE_DEVICE_SMB                 0x0000002e
260
        #define FILE_DEVICE_KS                  0x0000002f
261
        #define FILE_DEVICE_CHANGER             0x00000030
262
        #define FILE_DEVICE_SMARTCARD           0x00000031
263
        #define FILE_DEVICE_ACPI                0x00000032
264
        #define FILE_DEVICE_DVD                 0x00000033
265
        #define FILE_DEVICE_FULLSCREEN_VIDEO    0x00000034
266
        #define FILE_DEVICE_DFS_FILE_SYSTEM     0x00000035
267
        #define FILE_DEVICE_DFS_VOLUME          0x00000036
268
        #define FILE_DEVICE_SERENUM             0x00000037
269
        #define FILE_DEVICE_TERMSRV             0x00000038
270
        #define FILE_DEVICE_KSEC                0x00000039
271
272
} FILE_FS_DEVICE_INFORMATION;
273
274
typedef struct _FILE_FS_DRIVER_PATH_INFORMATION {
275
	BYTE					DriverInPath;
276
	union _Reserved {
277
		BYTE		bytes[3];
278
		DWORD		uint24:24;
279
	}					Reserved;
280
	DWORD					DriverNameLength;
281
	BYTE *					DriverName;
282
} FILE_FS_DRIVER_PATH_INFORMATION;
283
284
typedef struct _FILE_FS_VOLUME_INFORMATION {
285
	QWORD					VolumeCreationTime;
286
	DWORD					VolumeSerialNumber;
287
	DWORD					VolumeLabelLength;
288
	BYTE					SupportsObjects;
289
	BYTE					Reserved;
290
	BYTE *					VolumeLabel;
291
} FILE_FS_VOLUME_INFORMATION;
292
293
typedef struct _FILE_DIRECTORY_INFORMATION {
294
	DWORD					NextEntryOffset;
295
	DWORD					FileIndex;
296
	QWORD					CreationTime;
297
	QWORD					LastAccessTime;
298
	QWORD					LastWriteTime;
299
	QWORD					ChangeTime;
300
	QWORD					EndOfFile;
301
	QWORD					AllocationSize;
302
	DWORD					FileAttributes;
303
	DWORD					FileNameLength;
304
	BYTE *					FileName;
305
} FILE_DIRECTORY_INFORMATION;
306
307
typedef struct _FILE_FULL_DIR_INFORMATION {
308
	DWORD					NextEntryOffset;
309
	DWORD					FileIndex;
310
	QWORD					CreationTime;
311
	QWORD					LastAccessTime;
312
	QWORD					LastWriteTime;
313
	QWORD					ChangeTime;
314
	QWORD					EndOfFile;
315
	QWORD					AllocationSize;
316
	DWORD					FileAttributes;
317
	DWORD					FileNameLength;
318
	DWORD					EaSize;
319
	BYTE *					FileName;	
320
} FILE_FULL_DIR_INFORMATION;
321
322
typedef struct _FILE_FULL_EA_INFORMATION {
323
	DWORD					NextEntryOffset;
324
	BYTE					Flags;
325
	BYTE					EaNameLength;
326
	WORD					EaValueLength;
327
	BYTE *					EaName;
328
	BYTE *					EaValue;
329
330
	#define	FILE_NEED_EA			0x00000080
331
} FILE_FULL_EA_INFORMATION;
332
333
typedef struct _FILE_GET_EA_INFORMATION {
334
	DWORD					NextEntryOffset;
335
	BYTE					EaNameLength;
336
	BYTE *					EaName;
337
} FILE_GET_EA_INFORMATION, FILE_SET_EA_INFORMATION;
338
339
typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
340
	DWORD					NextEntryOffset;
341
	DWORD					FileIndex;
342
	QWORD					CreationTime;
343
	QWORD					LastAccessTime;
344
	QWORD					LastWriteTime;
345
	QWORD					ChangeTime;
346
	QWORD					EndOfFile;
347
	QWORD					AllocationSize;
348
	DWORD					FileAttributes;
349
	DWORD					FileNameLength;
350
	DWORD					EaSize;
351
	BYTE					ShortNameLength;
352
	BYTE					Reserved1;
353
	BYTE					ShortName[24];
354
	WORD					Reserved2;
355
	QWORD					FileId;
356
	BYTE *					FileName;
357
} FILE_ID_BOTH_DIR_INFORMATION;
358
359
typedef struct _FILE_ID_FULL_DIR_INFORMATION {
360
	DWORD					NextEntryOffset;
361
	DWORD					FileIndex;
362
	QWORD					CreationTime;
363
	QWORD					LastAccessTime;
364
	QWORD					LastWriteTime;
365
	QWORD					ChangeTime;
366
	QWORD					EndOfFile;
367
	QWORD					AllocationSize;
368
	DWORD					FileAttributes;
369
	DWORD					FileNameLength;
370
	DWORD					EaSize;
371
	DWORD					Reserved;
372
	QWORD					FileId;
373
	BYTE *					FileName;	
374
} FILE_ID_FULL_DIR_INFORMATION;
375
376
typedef struct _FILE_NAME_INFORMATION {
377
	DWORD					FileNameLength;
378
	BYTE					FileName[1024];
379
} FILE_NAME_INFORMATION;
380
381
typedef struct _FILE_NAMES_INFORMATION {
382
	DWORD					NextEntryOffset;
383
	DWORD					FileIndex;
384
	DWORD					FileNameLength;
385
	BYTE *					FileName;
386
} FILE_NAMES_INFORMATION;
387
388
typedef struct _FILE_RENAME_INFORMATION_V1 {
389
	BYTE					ReplaceIfExists;
390
	BYTE					Reserved[3];
391
	DWORD					RootDirectory;
392
	DWORD					FileNameLength;
393
	BYTE *					FileName;
394
} FILE_RENAME_INFORMATION_V1;
395
396
typedef struct _FILE_RENAME_INFORMATION {
397
	BYTE					ReplaceIfExists;
398
	BYTE					Reserved[7];
399
	QWORD					RootDirectory;
400
	DWORD					FileNameLength;
401
	BYTE *					FileName;
402
} FILE_RENAME_INFORMATION;
403
404
typedef struct _FILE_BASIC_INFORMATION {
405
	QWORD					CreationTime;
406
	QWORD					LastAccessTime;
407
	QWORD					LastWriteTime;
408
	QWORD					ChangeTime;
409
	DWORD					FileAttributes;
410
	DWORD					Reserved;
411
} FILE_BASIC_INFORMATION;
412
413
typedef struct _FILE_BOTH_DIR_INFORMATION {
414
	DWORD					NextEntryOffset;
415
	DWORD					FileIndex;
416
	QWORD					CreationTime;
417
	QWORD					LastAccessTime;
418
	QWORD					LastWriteTime;
419
	QWORD					ChangeTime;
420
	QWORD					EndOfFile;
421
	QWORD					AllocationSize;
422
	DWORD					FileAttributes;
423
	DWORD					FileNameLength;
424
	DWORD					EaSize;
425
	BYTE					ShortNameLength;
426
	BYTE					Reserved;
427
	BYTE					ShortName[24];
428
	BYTE					FileName[1024];
429
} FILE_BOTH_DIR_INFORMATION;
430
431
typedef struct _FILE_STANDARD_INFORMATION {
432
	QWORD					AllocationSize;
433
	QWORD					EndOfFile;
434
	DWORD					NumberOfLinks;
435
	BYTE					DeletePending;
436
	BYTE					Directory;
437
	WORD					Reserved;
438
} FILE_STANDARD_INFORMATION;
439
440
typedef struct _FILE_ALL_INFORMATION {
441
	FILE_BASIC_INFORMATION			BasicInformation;
442
	FILE_STANDARD_INFORMATION		StandardInformation;
443
	QWORD					InternalInformation;
444
	DWORD					EaInformation;
445
	DWORD					AccessInformation;
446
	QWORD					PositionInformation;
447
	DWORD					ModeInformation;
448
	DWORD					AlignmentInformation;
449
	FILE_NAME_INFORMATION			NameInformation;
450
451
	#define	FILE_BYTE_ALIGNMENT		0x00000000
452
	#define	FILE_WORD_ALIGNMENT		0x00000001
453
	#define	FILE_LONG_ALIGNMENT		0x00000003
454
	#define	FILE_QUAD_ALIGNMENT		0x00000007
455
	#define	FILE_OCTA_ALIGNMENT		0x0000000f
456
	#define	FILE_32_BYTE_ALIGNMENT		0x0000001f
457
	#define	FILE_64_BYTE_ALIGNMENT		0x0000003f
458
	#define	FILE_128_BYTE_ALIGNMENT		0x0000007f
459
	#define	FILE_256_BYTE_ALIGNMENT		0x000000ff
460
	#define	FILE_512_BYTE_ALIGNMENT		0x000001ff
461
} FILE_ALL_INFORMATION;
462
463
typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION {
464
	DWORD					FileAttributes;
465
	DWORD					ReparseTag;
466
} FILE_ATTRIBUTE_TAG_INFORMATION;
467
468
/***/
469
470
typedef struct _RDPDR_HEADER {
471
	WORD						Component;
472
	WORD						PacketId;
473
	void						(*__destructor)(struct _RDPDR_HEADER *);
474
	int						(*out)(struct _RDPDR_HEADER *, struct stream *);
475
	int						(*in)(struct _RDPDR_HEADER *, struct stream *);
476
477
	#define RDPDR_CTYP_CORE			0x4472
478
	#define RDPDR_CTYP_PRN			0x5052
479
	#define PAKID_CORE_SERVER_ANNOUNCE	0x496E
480
	#define PAKID_CORE_CLIENTID_CONFIRM	0x4343
481
	#define PAKID_CORE_CLIENT_NAME		0x434E
482
	#define PAKID_CORE_DEVICELIST_ANNOUNCE	0x4441
483
	#define PAKID_CORE_DEVICE_REPLY		0x6472
484
	#define PAKID_CORE_DEVICE_IOREQUEST	0x4952
485
	#define PAKID_CORE_DEVICE_IOCOMPLETION	0x4943
486
	#define PAKID_CORE_SERVER_CAPABILITY	0x5350
487
	#define PAKID_CORE_CLIENT_CAPABILITY	0x4350
488
	#define PAKID_CORE_DEVICELIST_REMOVE	0x444D
489
	#define PAKID_PRN_CACHE_DATA		0x5043
490
	#define PAKID_CORE_USER_LOGGEDON	0x554C
491
	#define PAKID_PRN_USING_XPS		0x5543
492
} RDPDR_HEADER;
493
494
typedef struct _CAPABILITY_HEADER {
495
	WORD						CapabilityType;
496
	WORD						CapabilityLength;
497
	DWORD						Version;
498
	void						(*__destructor)(struct _CAPABILITY_HEADER *);
499
	int						(*out)(struct _CAPABILITY_HEADER *, struct stream *);
500
	int						(*in)(struct _CAPABILITY_HEADER *, struct stream *);
501
502
	#define CAP_GENERAL_TYPE		0x0001
503
	#define CAP_PRINTER_TYPE		0x0002
504
	#define CAP_PORT_TYPE			0x0003
505
	#define CAP_DRIVE_TYPE			0x0004
506
	#define CAP_SMARTCARD_TYPE		0x0005
507
508
	#define GENERAL_CAPABILITY_VERSION_01	0x00000001
509
	#define GENERAL_CAPABILITY_VERSION_02	0x00000002
510
	#define PRINT_CAPABILITY_VERSION_01	0x00000001
511
	#define PORT_CAPABILITY_VERSION_01	0x00000001
512
	#define DRIVE_CAPABILITY_VERSION_01	0x00000001
513
	#define DRIVE_CAPABILITY_VERSION_02	0x00000002
514
	#define SMARTCARD_CAPABILITY_VERSION_01	0x00000001
515
} CAPABILITY_HEADER;
516
517
typedef struct _CAPABILITY_SET {
518
	CAPABILITY_HEADER				Header;
519
	BYTE *						capabilityData;
520
	void						(*__destructor)(struct _CAPABILITY_SET *);
521
	int						(*out)(struct _CAPABILITY_SET *, struct stream *);
522
	int						(*in)(struct _CAPABILITY_SET *, struct stream *);
523
} CAPABILITY_SET;
524
525
typedef struct _DEVICE_ANNOUNCE {
526
	DWORD						DeviceType;
527
	DWORD						DeviceId;
528
	BYTE						PreferredDosName[8];
529
	DWORD						DeviceDataLength;
530
	BYTE *						DeviceData;
531
	void *						item;
532
	void						(*__destructor)(struct _DEVICE_ANNOUNCE *);
533
	int						(*out)(struct _DEVICE_ANNOUNCE *, struct stream *);
534
	int						(*in)(struct _DEVICE_ANNOUNCE *, struct stream *);
535
} DEVICE_ANNOUNCE;
536
537
typedef struct _DEVICE_ANNOUNCE_STATIC {
538
	DWORD						DeviceType;
539
	DWORD						DeviceId;
540
	BYTE						PreferredDosName[8];
541
	DWORD						DeviceDataLength;
542
	BYTE						DeviceData[2048];
543
	void *						item;
544
	void						(*__destructor)(struct _DEVICE_ANNOUNCE *);
545
	int						(*out)(struct _DEVICE_ANNOUNCE *, struct stream *);
546
	int						(*in)(struct _DEVICE_ANNOUNCE *, struct stream *);
547
} DEVICE_ANNOUNCE_STATIC;
548
549
typedef struct _DR_DEVICE_IOREQUEST {
550
	struct _RDPDR_HEADER				Header;
551
	DWORD						DeviceId;
552
	DWORD						FileId;
553
	DWORD						CompletionId;
554
	DWORD						MajorFunction;
555
	DWORD						MinorFunction;
556
	void						(*__destructor)(struct _DR_DEVICE_IOREQUEST *);
557
	int						(*out)(struct _DR_DEVICE_IOREQUEST *, struct stream *);
558
	int						(*in)(struct _DR_DEVICE_IOREQUEST *, struct stream *);
559
560
	//
561
	//  Standard IRP Major codes
562
	//
563
	#define IRP_MJ_CREATE                       0x00
564
	#define IRP_MJ_CREATE_NAMED_PIPE            0x01
565
	#define IRP_MJ_CLOSE                        0x02
566
	#define IRP_MJ_READ                         0x03
567
	#define IRP_MJ_WRITE                        0x04
568
	#define IRP_MJ_QUERY_INFORMATION            0x05
569
	#define IRP_MJ_SET_INFORMATION              0x06
570
	#define IRP_MJ_QUERY_EA                     0x07
571
	#define IRP_MJ_SET_EA                       0x08
572
	#define IRP_MJ_FLUSH_BUFFERS                0x09
573
	#define IRP_MJ_QUERY_VOLUME_INFORMATION     0x0a
574
	#define IRP_MJ_SET_VOLUME_INFORMATION       0x0b
575
	#define IRP_MJ_DIRECTORY_CONTROL            0x0c
576
	#define	IRP_MJ_QUERY_DIRECTORY		    0x0c
577
	#define IRP_MJ_FILE_SYSTEM_CONTROL          0x0d
578
	#define IRP_MJ_DEVICE_CONTROL               0x0e
579
	#define IRP_MJ_INTERNAL_DEVICE_CONTROL      0x0f
580
	#define IRP_MJ_SHUTDOWN                     0x10
581
	#define IRP_MJ_LOCK_CONTROL                 0x11
582
	#define IRP_MJ_CLEANUP                      0x12
583
	#define IRP_MJ_CREATE_MAILSLOT              0x13
584
	#define IRP_MJ_QUERY_SECURITY               0x14
585
	#define IRP_MJ_SET_SECURITY                 0x15
586
	#define IRP_MJ_POWER                        0x16
587
	#define IRP_MJ_SYSTEM_CONTROL               0x17
588
	#define IRP_MJ_DEVICE_CHANGE                0x18
589
	#define IRP_MJ_QUERY_QUOTA                  0x19
590
	#define IRP_MJ_SET_QUOTA                    0x1a
591
	#define IRP_MJ_PNP                          0x1b
592
	#define IRP_MJ_MAXIMUM_FUNCTION             0x1b
593
594
	//
595
	//  IRP minor codes
596
	//
597
	#define IRP_MN_QUERY_DIRECTORY              0x01
598
	#define IRP_MN_NOTIFY_CHANGE_DIRECTORY      0x02
599
	#define IRP_MN_USER_FS_REQUEST              0x00
600
	#define IRP_MN_MOUNT_VOLUME                 0x01 
601
	#define IRP_MN_VERIFY_VOLUME                0x02 
602
	#define IRP_MN_LOAD_FILE_SYSTEM             0x03 
603
	#define IRP_MN_TRACK_LINK                   0x04 
604
	#define IRP_MN_LOCK                         0x01 
605
	#define IRP_MN_UNLOCK_SINGLE                0x02 
606
	#define IRP_MN_UNLOCK_ALL                   0x03 
607
	#define IRP_MN_UNLOCK_ALL_BY_KEY            0x04 
608
	#define IRP_MN_NORMAL                       0x00 
609
	#define IRP_MN_DPC                          0x01 
610
	#define IRP_MN_MDL                          0x02 
611
	#define IRP_MN_COMPLETE                     0x04 
612
	#define IRP_MN_COMPRESSED                   0x08 
613
	#define IRP_MN_MDL_DPC                      (IRP_MN_MDL | IRP_MN_DPC)
614
	#define IRP_MN_COMPLETE_MDL                 (IRP_MN_COMPLETE | IRP_MN_MDL)
615
	#define IRP_MN_COMPLETE_MDL_DPC             (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
616
	#define IRP_MN_SCSI_CLASS                   0x01 
617
	#define IRP_MN_START_DEVICE                 0x00 
618
	#define IRP_MN_QUERY_REMOVE_DEVICE          0x01 
619
	#define IRP_MN_REMOVE_DEVICE                0x02 
620
	#define IRP_MN_CANCEL_REMOVE_DEVICE         0x03 
621
	#define IRP_MN_STOP_DEVICE                  0x04 
622
	#define IRP_MN_QUERY_STOP_DEVICE            0x05 
623
	#define IRP_MN_CANCEL_STOP_DEVICE           0x06 
624
	#define IRP_MN_QUERY_DEVICE_RELATIONS       0x07 
625
	#define IRP_MN_QUERY_INTERFACE              0x08 
626
	#define IRP_MN_QUERY_CAPABILITIES           0x09 
627
	#define IRP_MN_QUERY_RESOURCES              0x0A 
628
	#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS  0x0B 
629
	#define IRP_MN_QUERY_DEVICE_TEXT            0x0C 
630
	#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D 
631
	#define IRP_MN_READ_CONFIG                  0x0F 
632
	#define IRP_MN_WRITE_CONFIG                 0x10 
633
	#define IRP_MN_EJECT                        0x11 
634
	#define IRP_MN_SET_LOCK                     0x12 
635
	#define IRP_MN_QUERY_ID                     0x13 
636
	#define IRP_MN_QUERY_PNP_DEVICE_STATE       0x14 
637
	#define IRP_MN_QUERY_BUS_INFORMATION        0x15 
638
	#define IRP_MN_DEVICE_USAGE_NOTIFICATION    0x16 
639
	#define IRP_MN_SURPRISE_REMOVAL             0x17 
640
	#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 
641
	#define IRP_MN_WAIT_WAKE                    0x00 
642
	#define IRP_MN_POWER_SEQUENCE               0x01 
643
	#define IRP_MN_SET_POWER                    0x02 
644
	#define IRP_MN_QUERY_POWER                  0x03 
645
	#define IRP_MN_QUERY_ALL_DATA               0x00 
646
	#define IRP_MN_QUERY_SINGLE_INSTANCE        0x01 
647
	#define IRP_MN_CHANGE_SINGLE_INSTANCE       0x02 
648
	#define IRP_MN_CHANGE_SINGLE_ITEM           0x03 
649
	#define IRP_MN_ENABLE_EVENTS                0x04 
650
	#define IRP_MN_DISABLE_EVENTS               0x05 
651
	#define IRP_MN_ENABLE_COLLECTION            0x06 
652
	#define IRP_MN_DISABLE_COLLECTION           0x07 
653
	#define IRP_MN_REGINFO                      0x08 
654
	#define IRP_MN_EXECUTE_METHOD               0x09 
655
656
} DR_DEVICE_IOREQUEST;
657
658
typedef struct _DR_CREATE_REQ {
659
	DR_DEVICE_IOREQUEST				DeviceIoRequest;
660
	DWORD						DesiredAccess;
661
	QWORD						AllocationSize;
662
	DWORD						FileAttributes;
663
	DWORD						SharedAccess;
664
	DWORD						CreateDisposition;
665
	DWORD						CreateOptions;
666
	DWORD						PathLength;
667
	BYTE						Path[512];
668
	void						(*__destructor)(struct _DR_CREATE_REQ *);
669
	int						(*out)(struct _DR_CREATE_REQ *, struct stream *);
670
	int						(*in)(struct _DR_CREATE_REQ *, struct stream *);
671
672
	/* For "File_Pipe_Printer_Access_Mask" (4 bytes) */
673
	#define	FILE_READ_DATA	0x00000001
674
	#define	FILE_WRITE_DATA 0x00000002
675
	#define	FILE_APPEND_DATA 0x00000004
676
	#define	FILE_READ_EA 0x00000008
677
	#define	FILE_WRITE_EA 0x00000010
678
	#define	FILE_EXECUTE 0x00000020
679
	#define	FILE_READ_ATTRIBUTES 0x00000080
680
	#define	FILE_WRITE_ATTRIBUTES 0x00000100
681
	#define	DELETE 0x00010000
682
	#define	READ_CONTROL 0x00020000
683
	#define	WRITE_DAC 0x00040000
684
	#define	WRITE_OWNER 0x00080000
685
	#define	SYNCHRONIZE 0x00100000
686
	#define	ACCESS_SYSTEM_SECURITY 0x01000000
687
	#define	MAXIMUM_ALLOWED 0x02000000
688
	#define	GENERIC_ALL 0x10000000
689
	#define	GENERIC_EXECUTE 0x20000000
690
	#define	GENERIC_WRITE 0x40000000
691
	#define	GENERIC_READ 0x80000000
692
693
	/* For "directory_access_mask" (4 bytes) */
694
	#define	FILE_LIST_DIRECTORY 0x00000001
695
	#define	FILE_ADD_FILE 0x00000002
696
	#define	FILE_ADD_SUBDIRECTORY 0x00000004
697
	#define	FILE_TRAVERSE 0x00000020
698
	#define	FILE_DELETE_CHILD 0x00000040
699
700
	/* File attributes */
701
	#define	FILE_ATTRIBUTE_ARCHIVE		0x00000020
702
	#define	FILE_ATTRIBUTE_COMPRESSED	0x00000800
703
	#define	FILE_ATTRIBUTE_DIRECTORY	0x00000010
704
	#define	FILE_ATTRIBUTE_ENCRYPTED	0x00004000
705
	#define	FILE_ATTRIBUTE_HIDDEN		0x00000002
706
	#define	FILE_ATTRIBUTE_NORMAL		0x00000080
707
	#define	FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
708
	#define	FILE_ATTRIBUTE_OFFLINE		0x00001000
709
	#define	FILE_ATTRIBUTE_READONLY		0x00000001
710
	#define	FILE_ATTRIBUTE_REPARSE_POINT	0x00000400
711
	#define	FILE_ATTRIBUTE_SPARSE_FILE	0x00000200
712
	#define	FILE_ATTRIBUTE_SYSTEM		0x00000004
713
	#define	FILE_ATTRIBUTE_TEMPORARY	0x00000100
714
715
	/* Shared access */
716
	#define	FILE_SHARE_READ			0x00000001
717
	#define	FILE_SHARE_WRITE		0x00000002
718
	#define	FILE_SHARE_DELETE		0x00000004
719
720
	/* Dispositions */
721
	#define	FILE_OPEN			0x00000001
722
	#define	FILE_CREATE			0x00000002
723
	#define	FILE_OPEN_IF			0x00000003
724
	#define	FILE_OVERWRITE			0x00000004
725
	#define	FILE_OVERWRITE_IF		0x00000005
726
727
	/* Create options */
728
	#define	FILE_DIRECTORY_FILE 0x00000001
729
	#define	FILE_WRITE_THROUGH 0x00000002
730
	#define	FILE_SEQUENTIAL_ONLY 0x00000004
731
	#define	FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
732
	#define	FILE_SYNCHRONOUS_IO_ALERT 0x00000010
733
	#define	FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
734
	#define	FILE_NON_DIRECTORY_FILE 0x00000040
735
	#define	FILE_COMPLETE_IF_OPLOCKED 0x00000100
736
	#define	FILE_NO_EA_KNOWLEDGE 0x00000200
737
	#define	FILE_RANDOM_ACCESS 0x00000800
738
	#define	FILE_DELETE_ON_CLOSE 0x00001000
739
	#define	FILE_OPEN_BY_FILE_ID 0x00002000
740
	#define	FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
741
	#define	FILE_NO_COMPRESSION 0x00008000
742
	#define	FILE_RESERVE_OPFILTER 0x00100000
743
	#define	FILE_OPEN_REPARSE_POINT 0x00200000
744
	#define	FILE_OPEN_NO_RECALL 0x00400000
745
	#define	FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
746
747
} DR_CREATE_REQ, DR_PORT_CREATE_REQ;
748
749
typedef struct _DR_CLOSE_REQ {
750
	DR_DEVICE_IOREQUEST				DeviceIoRequest;
751
	BYTE						Padding[32];	
752
	void						(*__destructor)(struct _DR_CLOSE_REQ *);
753
	int						(*in)(struct _DR_CLOSE_REQ *, struct stream *);
754
	int						(*out)(struct _DR_CLOSE_REQ *, struct stream *);
755
} DR_CLOSE_REQ;
756
757
typedef struct _DR_READ_REQ {
758
	DR_DEVICE_IOREQUEST				DeviceIoRequest;
759
	DWORD						Length;
760
	QWORD						Offset;
761
	BYTE						Padding[20];
762
	void						(*__destructor)(struct _DR_READ_REQ *);
763
	int						(*in)(struct _DR_READ_REQ *, struct stream *);
764
	int						(*out)(struct _DR_READ_REQ *, struct stream *);
765
} DR_READ_REQ, DR_PORT_READ_REQ;
766
767
typedef struct _DR_WRITE_REQ {
768
	DR_DEVICE_IOREQUEST				DeviceIoRequest;
769
	DWORD						Length;
770
	QWORD						Offset;
771
	BYTE						Padding[20];
772
	BYTE *						WriteData;
773
	void						(*__destructor)(struct _DR_WRITE_REQ *);
774
	int						(*in)(struct _DR_WRITE_REQ *, struct stream *);
775
	int						(*out)(struct _DR_WRITE_REQ *, struct stream *);
776
} DR_WRITE_REQ, DR_PORT_WRITE_REQ;
777
778
typedef struct _DR_CONTROL_REQ {
779
	DR_DEVICE_IOREQUEST				DeviceIoRequest;
780
	DWORD						OutputBufferLength;
781
	DWORD						InputBufferLength;
782
	DWORD						IoControlCode;
783
	BYTE						Padding[20];
784
	BYTE *						InputBuffer;
785
	void						(*__destructor)(struct _DR_CONTROL_REQ *);
786
	int						(*in)(struct _DR_CONTROL_REQ *, struct stream *);
787
	int						(*out)(struct _DR_CONTROL_REQ *, struct stream *);
788
} DR_CONTROL_REQ, DR_PORT_CONTROL_REQ;
789
790
typedef struct _DR_DEVICE_IOCOMPLETION {
791
	RDPDR_HEADER					Header;
792
	DWORD						DeviceId;
793
	DWORD						CompletionId;
794
	NTSTATUS					IoStatus;
795
	void						(*__destructor)(struct _DR_DEVICE_IOCOMPLETION *);
796
	int						(*in)(struct _DR_DEVICE_IOCOMPLETION *, struct stream *);
797
	int						(*out)(struct _DR_DEVICE_IOCOMPLETION *, struct stream *);
798
} DEVICE_IOCOMPLETION, DR_DEVICE_IOCOMPLETION;
799
800
typedef struct _DR_CREATE_RSP {
801
	DR_DEVICE_IOCOMPLETION				DeviceIoReply;
802
	DWORD						FileId;
803
	BYTE						Information;
804
	void						(*__destructor)(struct _DR_CREATE_RSP *);
805
	int						(*in)(struct _DR_CREATE_RSP *, struct stream *);
806
	int						(*out)(struct _DR_CREATE_RSP *, struct stream *);
807
808
	#define	FILE_SUPERSEDED 0x00000000
809
	#define	FILE_OPENED 0x00000001
810
	#define	FILE_OVERWRITTEN 0x00000003
811
} DR_CREATE_RSP, DR_PORT_CREATE_RSP;
812
813
typedef struct _DR_CLOSE_RSP {
814
	DR_DEVICE_IOCOMPLETION				DeviceIoReply;
815
	BYTE						Padding[5];	
816
	void						(*__destructor)(struct _DR_CLOSE_RSP *);
817
	int						(*in)(struct _DR_CLOSE_RSP *, struct stream *);
818
	int						(*out)(struct _DR_CLOSE_RSP *, struct stream *);
819
} DR_CLOSE_RSP, DR_PORT_CLOSE_RSP;
820
821
typedef struct _DR_READ_RSP {
822
	DR_DEVICE_IOCOMPLETION				DeviceIoReply;
823
	DWORD						Length;
824
	BYTE *						ReadData;
825
	void						(*__destructor)(struct _DR_READ_RSP *);
826
	int						(*in)(struct _DR_READ_RSP *, struct stream *);
827
	int						(*out)(struct _DR_READ_RSP *, struct stream *);
828
} DR_READ_RSP, DR_DRIVE_READ_RSP, DR_PORT_READ_RSP;
829
830
typedef struct _DR_WRITE_RSP {
831
	DR_DEVICE_IOCOMPLETION				DeviceIoReply;
832
	DWORD						Length;
833
	BYTE						Padding;
834
	void						(*__destructor)(struct _DR_WRITE_RSP *);
835
	int						(*in)(struct _DR_WRITE_RSP *, struct stream *);
836
	int						(*out)(struct _DR_WRITE_RSP *, struct stream *);
837
} DR_WRITE_RSP, DR_DRIVE_WRITE_RSP, DR_PORT_WRITE_RSP;
838
839
typedef struct _DR_CONTROL_RSP {
840
	DR_DEVICE_IOCOMPLETION				DeviceIoReply;
841
	DWORD						OutputBufferLength;
842
	BYTE *						OutputBuffer;
843
	void						(*__destructor)(struct _DR_CONTROL_RSP *);
844
	int						(*in)(struct _DR_CONTROL_RSP *, struct stream *);
845
	int						(*out)(struct _DR_CONTROL_RSP *, struct stream *);
846
} DR_CONTROL_RSP, DR_DRIVE_CONTROL_RSP, DR_PORT_CONTROL_RSP;
847
848
typedef struct _RDP_LOCK_INFO {
849
	QWORD						Length;
850
	QWORD						Offset;
851
	void						(*__destructor)(struct _RDP_LOCK_INFO *);
852
	int						(*in)(struct _RDP_LOCK_INFO *, struct stream *);
853
	int						(*out)(struct _RDP_LOCK_INFO *, struct stream *);
854
} RDP_LOCK_INFO;
855
856
typedef struct _DR_CORE_DEVICE_ANNOUNCE_RSP {
857
	RDPDR_HEADER					Header;
858
	DWORD						DeviceId;
859
	DWORD						ResultCode;
860
	void						(*__destructor)(struct _DR_CORE_DEVICE_ANNOUNCE_RSP *);
861
	int						(*in)(struct _DR_CORE_DEVICE_ANNOUNCE_RSP *, struct stream *);
862
	int						(*out)(struct _DR_CORE_DEVICE_ANNOUNCE_RSP *, struct stream *);
863
} DR_CORE_DEVICE_ANNOUNCE_RSP;
864
865
typedef struct _DR_CORE_SERVER_ANNOUNCE_REQ {
866
	RDPDR_HEADER					Header;
867
	WORD						VersionMajor;	/* must be set to 0x0001 */
868
	WORD						VersionMinor;	/* may be 0x000C (Vista, Windows 7, Server 2008), 0x000A (Server 2003 SP2), 0x0006 (XP SP3), 0x0005 (Windows XP, Windows XP SP1, Windows XP SP2, Windows Server 2003, and Windows Server 2003 with SP1), or 0x0002 (Windows 2000) */
869
	DWORD						ClientId;
870
	void						(*__destructor)(struct _DR_CORE_SERVER_ANNOUNCE_REQ *);
871
	int						(*in)(struct _DR_CORE_SERVER_ANNOUNCE_REQ *, struct stream *);
872
	int						(*out)(struct _DR_CORE_SERVER_ANNOUNCE_REQ *, struct stream *);
873
} DR_CORE_SERVER_ANNOUNCE_REQ;
874
875
typedef struct _DR_CORE_SERVER_ANNOUNCE_RSP {
876
	RDPDR_HEADER					Header;
877
	WORD						VersionMajor;	/* must be set to 0x0001 */
878
	WORD						VersionMinor;	/* may be 0x000C (Vista, Windows 7, Server 2008), 0x000A (Server 2003 SP2), 0x0006 (XP SP3), 0x0005 (Windows XP, Windows XP SP1, Windows XP SP2, Windows Server 2003, and Windows Server 2003 with SP1), or 0x0002 (Windows 2000) */
879
	DWORD						ClientId;
880
	void						(*__destructor)(struct _DR_CORE_SERVER_ANNOUNCE_RSP *);
881
	int						(*in)(struct _DR_CORE_SERVER_ANNOUNCE_RSP *, struct stream *);
882
	int						(*out)(struct _DR_CORE_SERVER_ANNOUNCE_RSP *, struct stream *);
883
} DR_CORE_SERVER_ANNOUNCE_RSP;
884
885
typedef struct _DR_CORE_CLIENT_NAME_REQ {
886
	RDPDR_HEADER				Header;
887
	DWORD					UnicodeFlag;
888
	DWORD					CodePage;
889
	DWORD					ComputerNameLen;
890
	BYTE *					ComputerName;
891
	void					(*__destructor)(struct _DR_CORE_CLIENT_NAME_REQ *);
892
	int					(*in)(struct _DR_CORE_CLIENT_NAME_REQ *, struct stream *);
893
	int					(*out)(struct _DR_CORE_CLIENT_NAME_REQ *, struct stream *);
894
} DR_CORE_CLIENT_NAME_REQ;
895
896
typedef struct _DR_CORE_USER_LOGGEDON {
897
	RDPDR_HEADER				Header;
898
	void					(*__destructor)(struct _DR_CORE_USER_LOGGEDON *);
899
	int					(*in)(struct _DR_CORE_USER_LOGGEDON *, struct stream *);
900
	int					(*out)(struct _DR_CORE_USER_LOGGEDON *, struct stream *);
901
} DR_CORE_USER_LOGGEDON;
902
903
typedef struct _DR_CORE_SERVER_CLIENTID_CONFIRM {
904
	RDPDR_HEADER				Header;
905
	WORD					VersionMajor;	/* must be set to 0x0001 */
906
	WORD					VersionMinor;	/* may be 0x000C (Vista, Windows 7, Server 2008), 0x000A (Server 2003 SP2), 0x0006 (XP SP3), 0x0005 (Windows XP, Windows XP SP1, Windows XP SP2, Windows Server 2003, and Windows Server 2003 with SP1), or 0x0002 (Windows 2000) */
907
	DWORD					ClientId;
908
	void					(*__destructor)(struct _DR_CORE_SERVER_CLIENTID_CONFIRM *);
909
	int					(*in)(struct _DR_CORE_SERVER_CLIENTID_CONFIRM *, struct stream *);
910
	int					(*out)(struct _DR_CORE_SERVER_CLIENTID_CONFIRM *, struct stream *);
911
} DR_CORE_SERVER_CLIENTID_CONFIRM;
912
913
typedef struct _DR_CORE_CAPABILITY_REQ {
914
	RDPDR_HEADER				Header;
915
	WORD					numCapabilities;
916
	WORD					Padding;
917
	CAPABILITY_SET *			CapabilityMessage;
918
	void					(*__destructor)(struct _DR_CORE_CAPABILITY_REQ *);
919
	int					(*out)(struct _DR_CORE_CAPABILITY_REQ *, struct stream *);
920
	int					(*in)(struct _DR_CORE_CAPABILITY_REQ *, struct stream *);
921
} DR_CORE_CAPABILITY_REQ, DR_CORE_CAPABILITY_RSP;
922
923
typedef struct _GENERAL_CAPS_SET {
924
	CAPABILITY_HEADER			Header;
925
	DWORD					osType;
926
	DWORD					osVersion;
927
	WORD					protocolMajorVersion;
928
	WORD					protocolMinorVersion;
929
	DWORD					ioCode1;
930
	DWORD					ioCode2;
931
	DWORD					extendedPDU;
932
	DWORD					extraFlags1;
933
	DWORD					extraFlags2;
934
	DWORD					SpecialTypeDeviceCap;
935
	void					(*__destructor)(struct _GENERAL_CAPS_SET *);
936
	int					(*out)(struct _GENERAL_CAPS_SET *, struct stream *);
937
	int					(*in)(struct _GENERAL_CAPS_SET *, struct stream *);
938
939
	#define RDPDR_IRP_MJ_CREATE 0x00000001
940
	#define RDPDR_IRP_MJ_CLEANUP 0x00000002
941
	#define RDPDR_IRP_MJ_CLOSE 0x00000004
942
	#define RDPDR_IRP_MJ_READ 0x00000008
943
	#define RDPDR_IRP_MJ_WRITE 0x00000010
944
	#define RDPDR_IRP_MJ_FLUSH_BUFFERS 0x00000020
945
	#define RDPDR_IRP_MJ_SHUTDOWN 0x00000040
946
	#define RDPDR_IRP_MJ_DEVICE_CONTROL 0x00000080
947
	#define RDPDR_IRP_MJ_QUERY_VOLUME_INFORMATION 0x00000100
948
	#define RDPDR_IRP_MJ_SET_VOLUME_INFORMATION 0x00000200
949
	#define RDPDR_IRP_MJ_QUERY_INFORMATION 0x00000400
950
	#define RDPDR_IRP_MJ_SET_INFORMATION 0x00000800
951
	#define RDPDR_IRP_MJ_DIRECTORY_CONTROL 0x00001000
952
	#define RDPDR_IRP_MJ_LOCK_CONTROL 0x00002000
953
	#define RDPDR_IRP_MJ_QUERY_SECURITY 0x00004000
954
	#define RDPDR_IRP_MJ_SET_SECURITY 0x00008000
955
956
	#define RDPDR_DEVICE_REMOVE_PDUS 0x00000001
957
	#define RDPDR_CLIENT_DISPLAY_NAME_PDU 0x00000002
958
	#define RDPDR_USER_LOGGEDON_PDU 0x00000004
959
960
	#define ENABLE_ASYNCIO 0x00000001
961
} GENERAL_CAPS_SET;
962
963
typedef struct _PRINTER_CAPS_SET {
964
	CAPABILITY_HEADER		Header;
965
	void				(*__destructor)(struct _PRINTER_CAPS_SET *);
966
	int				(*out)(struct _PRINTER_CAPS_SET *, struct stream *);
967
	int				(*in)(struct _PRINTER_CAPS_SET *, struct stream *);
968
} PRINTER_CAPS_SET;
969
970
typedef struct _PORT_CAPS_SET {
971
	CAPABILITY_HEADER		Header;
972
	void				(*__destructor)(struct _PORT_CAPS_SET *);
973
	int				(*out)(struct _PORT_CAPS_SET *, struct stream *);
974
	int				(*in)(struct _PORT_CAPS_SET *, struct stream *);
975
} PORT_CAPS_SET;
976
977
typedef struct _DRIVE_CAPS_SET {
978
	CAPABILITY_HEADER		Header;
979
	void				(*__destructor)(struct _DRIVE_CAPS_SET *);
980
	int				(*out)(struct _DRIVE_CAPS_SET *, struct stream *);
981
	int				(*in)(struct _DRIVE_CAPS_SET *, struct stream *);
982
} DRIVE_CAPS_SET;
983
984
typedef struct _SMARTCARD_CAPS_SET {
985
	CAPABILITY_HEADER		Header;
986
	void				(*__destructor)(struct _SMARTCARD_CAPS_SET *);
987
	int				(*out)(struct _SMARTCARD_CAPS_SET *, struct stream *);
988
	int				(*in)(struct _SMARTCARD_CAPS_SET *, struct stream *);
989
} SMARTCARD_CAPS_SET;
990
991
typedef struct _DR_CORE_DEVICELIST_ANNOUNCE_REQ {
992
	RDPDR_HEADER			Header;
993
	DWORD				DeviceCount;
994
	DEVICE_ANNOUNCE *		DeviceList;
995
	void				(*__destructor)(struct _DR_CORE_DEVICELIST_ANNOUNCE_REQ *);
996
	int				(*out)(struct _DR_CORE_DEVICELIST_ANNOUNCE_REQ *, struct stream *);
997
	int				(*in)(struct _DR_CORE_DEVICELIST_ANNOUNCE_REQ *, struct stream *);
998
} DR_CORE_DEVICELIST_ANNOUNCE_REQ;
999
1000
typedef struct _DR_DEVICELIST_ANNOUNCE {
1001
	RDPDR_HEADER				Header;
1002
	DWORD					DeviceCount;
1003
	DEVICE_ANNOUNCE **			DeviceList;
1004
	void					(*__destructor)(struct _DR_DEVICELIST_ANNOUNCE *);
1005
	int					(*in)(struct _DR_DEVICELIST_ANNOUNCE *, struct stream *);
1006
	int					(*out)(struct _DR_DEVICELIST_ANNOUNCE *, struct stream *);
1007
} DR_DEVICELIST_ANNOUNCE;
1008
1009
typedef struct _DR_DEVICELIST_ANNOUNCE_STATIC {
1010
	RDPDR_HEADER				Header;
1011
	DWORD					DeviceCount;
1012
	DEVICE_ANNOUNCE_STATIC			DeviceList[96];
1013
	void					(*__destructor)(struct _DR_DEVICELIST_ANNOUNCE *);
1014
	int					(*in)(struct _DR_DEVICELIST_ANNOUNCE *, struct stream *);
1015
	int					(*out)(struct _DR_DEVICELIST_ANNOUNCE *, struct stream *);
1016
} DR_DEVICELIST_ANNOUNCE_STATIC;
1017
1018
typedef struct _DR_DEVICELIST_REMOVE {
1019
	RDPDR_HEADER				Header;
1020
	DWORD					DeviceCount;
1021
	DWORD *					DeviceIds;
1022
	void					(*__destructor)(struct _DR_DEVICELIST_REMOVE *);
1023
	int					(*in)(struct _DR_DEVICELIST_REMOVE *, struct stream *);
1024
	int					(*out)(struct _DR_DEVICELIST_REMOVE *, struct stream *);
1025
} DR_DEVICELIST_REMOVE;
1026
1027
1028
typedef struct _DR_DRIVE_CORE_DEVICE_IOREQUEST {
1029
	DR_DEVICE_IOREQUEST		Header;
1030
	void				(*__destructor)(struct _DR_DRIVE_CORE_DEVICE_IOREQUEST *);
1031
	int				(*in)(struct _DR_DRIVE_CORE_DEVICE_IOREQUEST *, struct stream *);
1032
	int				(*out)(struct _DR_DRIVE_CORE_DEVICE_IOREQUEST *, struct stream *);
1033
} DR_DRIVE_CORE_DEVICE_IOREQUEST;
1034
1035
typedef struct _DR_DRIVE_CREATE_REQ {
1036
	DR_CREATE_REQ				DeviceCreateRequest;
1037
	void					(*__destructor)(struct _DR_DRIVE_CREATE_REQ *);
1038
	int					(*out)(struct _DR_DRIVE_CREATE_REQ *, struct stream *);
1039
	int					(*in)(struct _DR_DRIVE_CREATE_REQ *, struct stream *);
1040
} DR_DRIVE_CREATE_REQ;
1041
1042
typedef struct _DR_DRIVE_CLOSE_REQ {
1043
	DR_CLOSE_REQ				DeviceCloseRequest;
1044
	void					(*__destructor)(struct _DR_DRIVE_CLOSE_REQ *);
1045
	int					(*out)(struct _DR_DRIVE_CLOSE_REQ *, struct stream *);
1046
	int					(*in)(struct _DR_DRIVE_CLOSE_REQ *, struct stream *);
1047
} DR_DRIVE_CLOSE_REQ;
1048
1049
typedef struct _DR_DRIVE_READ_REQ {
1050
	DR_READ_REQ				DeviceReadRequest;
1051
	void					(*__destructor)(struct _DR_DRIVE_READ_REQ *);
1052
	int					(*out)(struct _DR_DRIVE_READ_REQ *, struct stream *);
1053
	int					(*in)(struct _DR_DRIVE_READ_REQ *, struct stream *);
1054
} DR_DRIVE_READ_REQ;
1055
1056
typedef struct _DR_DRIVE_WRITE_REQ {
1057
	DR_WRITE_REQ				DeviceWriteRequest;
1058
	void					(*__destructor)(struct _DR_DRIVE_WRITE_REQ *);
1059
	int					(*out)(struct _DR_DRIVE_WRITE_REQ *, struct stream *);
1060
	int					(*in)(struct _DR_DRIVE_WRITE_REQ *, struct stream *);
1061
} DR_DRIVE_WRITE_REQ;
1062
1063
typedef struct _DR_DRIVE_CONTROL_REQ {
1064
	DR_CONTROL_REQ				Header;
1065
	void					(*__destructor)(struct _DR_DRIVE_CONTROL_REQ *);
1066
	int					(*out)(struct _DR_DRIVE_CONTROL_REQ *, struct stream *);
1067
	int					(*in)(struct _DR_DRIVE_CONTROL_REQ *, struct stream *);
1068
1069
	#define	FSCTL_CREATE_OR_GET_OBJECT_ID		0x900c0
1070
	#define	FSCTL_DELETE_OBJECT_ID			0x900a0
1071
	#define	FSCTL_DELETE_REPARSE_POINT		0x900ac
1072
	#define	FSCTL_FILESYSTEM_GET_STATISTICS		0x90060
1073
	#define	FSCTL_FIND_FILES_BY_SID			0x9008f
1074
	#define	FSCTL_GET_COMPRESSION			0x9003c
1075
	#define	FSCTL_GET_NTFS_VOLUME_DATA		0x90064
1076
	#define	FSCTL_GET_OBJECT_ID			0x9009c
1077
	#define	FSCTL_GET_REPARSE_POINT			0x900a8
1078
	#define	FSCTL_GET_RETRIEVAL_POINTERS		0x90073
1079
	#define	FSCTL_IS_PATHNAME_VALID			0x9002c
1080
	#define	FSCTL_LMR_GET_LINK_TRACKING_INFORMATION	0x1400e8
1081
	#define	FSCTL_LMR_SET_LINK_TRACKING_INFORMATION	0x1400ec
1082
	#define	FSCTL_PIPE_TRANSCEIVE			0x11c017
1083
	#define	FSCTL_PIPE_WAIT				0x110018
1084
	#define	FSCTL_QUERY_ALLOCATED_RANGES		0x940cf
1085
	#define	FSCTL_READ_FILE_USN_DATA		0x900eb
1086
	#define	FSCTL_RECALL_FILE			0x90117
1087
	#define	FSCTL_SET_COMPRESSION			0x9c040
1088
	#define	FSCTL_SET_ENCRYPTION			0x900D7
1089
	#define	FSCTL_SET_OBJECT_ID			0x90098
1090
	#define	FSCTL_SET_OBJECT_ID_EXTENDED		0x900bc
1091
	#define	FSCTL_SET_REPARSE_POINT			0x900a4
1092
	#define	FSCTL_SET_SHORT_NAME_BEHAVIOR		0x901B4
1093
	#define	FSCTL_SET_SPARSE			0x900c4
1094
	#define	FSCTL_SET_ZERO_DATA			0x980c8
1095
	#define	FSCTL_SET_ZERO_ON_DEALLOCATION		0x90194
1096
	#define	FSCTL_SIS_COPYFILE			0x90100
1097
	#define	FSCTL_WRITE_USN_CLOSE_RECORD		0x900ef
1098
1099
#ifndef	NT_IOCTLS
1100
#define	NT_IOCTLS
1101
1102
	#define IOCTL_SERIAL_SET_BAUD_RATE		0x001B0004
1103
	#define IOCTL_SERIAL_GET_BAUD_RATE		0x001B0050
1104
	#define IOCTL_SERIAL_SET_LINE_CONTROL		0x001B000C
1105
	#define IOCTL_SERIAL_GET_LINE_CONTROL		0x001B0054
1106
	#define IOCTL_SERIAL_SET_TIMEOUTS		0x001B001C
1107
	#define IOCTL_SERIAL_GET_TIMEOUTS		0x001B0020
1108
	#define IOCTL_SERIAL_SET_CHARS			0x001B0058
1109
	#define IOCTL_SERIAL_GET_CHARS			0x001B005C
1110
	#define IOCTL_SERIAL_SET_DTR			0x001B0024
1111
	#define IOCTL_SERIAL_CLR_DTR			0x001B0028
1112
	#define IOCTL_SERIAL_RESET_DEVICE		0x001B002C
1113
	#define IOCTL_SERIAL_SET_RTS			0x001B0030
1114
	#define IOCTL_SERIAL_CLR_RTS			0x001B0034
1115
	#define IOCTL_SERIAL_SET_XOFF			0x001B0038
1116
	#define IOCTL_SERIAL_SET_XON			0x001B003C
1117
	#define IOCTL_SERIAL_SET_BREAK_ON		0x001B0010
1118
	#define IOCTL_SERIAL_SET_BREAK_OFF		0x001B0014
1119
	#define IOCTL_SERIAL_SET_QUEUE_SIZE		0x001B0008
1120
	#define IOCTL_SERIAL_GET_WAIT_MASK		0x001B0040
1121
	#define IOCTL_SERIAL_SET_WAIT_MASK		0x001B0044
1122
	#define IOCTL_SERIAL_WAIT_ON_MASK		0x001B0048
1123
	#define IOCTL_SERIAL_IMMEDIATE_CHAR		0x001B0018
1124
	#define IOCTL_SERIAL_PURGE			0x001B004C
1125
	#define IOCTL_SERIAL_GET_HANDFLOW		0x001B0060
1126
	#define IOCTL_SERIAL_SET_HANDFLOW		0x001B0064
1127
	#define IOCTL_SERIAL_GET_MODEMSTATUS		0x001B0068
1128
	#define IOCTL_SERIAL_GET_DTRRTS			0x001B0078
1129
	#define IOCTL_SERIAL_GET_COMMSTATUS		0x001B0084
1130
	#define IOCTL_SERIAL_GET_PROPERTIES		0x001B0074
1131
	#define IOCTL_SERIAL_XOFF_COUNTER		0x001B0070
1132
	#define IOCTL_SERIAL_LSRMST_INSERT		0x001B007C
1133
	#define IOCTL_SERIAL_CONFIG_SIZE		0x001B0080
1134
	#define IOCTL_SERIAL_GET_STATS			0x001B008C
1135
	#define IOCTL_SERIAL_CLEAR_STATS		0x001B0090
1136
	#define IOCTL_SERIAL_GET_MODEM_CONTROL		0x001B0094
1137
	#define IOCTL_SERIAL_SET_MODEM_CONTROL		0x001B0098
1138
	#define IOCTL_SERIAL_SET_FIFO_CONTROL		0x001B009C
1139
	#define IOCTL_PAR_QUERY_INFORMATION		0x00160004
1140
	#define IOCTL_PAR_SET_INFORMATION		0x00160008
1141
	#define IOCTL_PAR_QUERY_DEVICE_ID		0x0016000C
1142
	#define IOCTL_PAR_QUERY_DEVICE_ID_SIZE		0x00160010
1143
	#define IOCTL_IEEE1284_GET_MODE			0x00160014
1144
	#define IOCTL_IEEE1284_NEGOTIATE		0x00160018
1145
	#define IOCTL_PAR_SET_WRITE_ADDRESS		0x0016001C
1146
	#define IOCTL_PAR_SET_READ_ADDRESS		0x00160020
1147
	#define IOCTL_PAR_GET_DEVICE_CAPS		0x00160024
1148
	#define IOCTL_PAR_GET_DEFAULT_MODES		0x00160028
1149
	#define IOCTL_PAR_QUERY_RAW_DEVICE_ID		0x00160030
1150
	#define IOCTL_PAR_IS_PORT_FREE			0x00160054
1151
1152
#endif	/* NT_IOCTLS */
1153
1154
} DR_DRIVE_CONTROL_REQ;
1155
1156
typedef struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ {
1157
	DR_DEVICE_IOREQUEST			DeviceIoRequest;
1158
	DWORD					FsInformationClass;
1159
	DWORD					Length;
1160
	BYTE					Padding[24];
1161
	union _QueryVolumeBuffer {
1162
	  BYTE *					bytes, byteArray, buf;
1163
	  unsigned char *		 		ucharArray, uchars;
1164
	  char *	 				str, charArray, chars;
1165
	  struct _FILE_FS_VOLUME_INFORMATION *		FsVolumeInformation;
1166
	  struct _FILE_FS_SIZE_INFORMATION *		FsSizeInformation;
1167
	  struct _FILE_FS_FULL_SIZE_INFORMATION *	FsFullSizeInformation;
1168
	  struct _FILE_FS_DEVICE_INFORMATION *		FsDeviceInformation;
1169
	  struct _FILE_FS_ATTRIBUTE_INFORMATION *	FsAttributeInformation;
1170
	}					QueryVolumeBuffer;
1171
	void					(*__destructor)(struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *);
1172
	int					(*out)(struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *, struct stream *);
1173
	int					(*in)(struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *, struct stream *);
1174
1175
	#define	FileFsVolumeInformation		0x00000001
1176
	#define	FileFsSizeInformation		0x00000003
1177
	#define	FileFsAttributeInformation	0x00000005
1178
	#define	FileFsFullSizeInformation	0x00000007
1179
	#define	FileFsDeviceInformation		0x00000004
1180
} DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ;
1181
1182
typedef struct _DR_DRIVE_SET_VOLUME_INFORMATION_REQ {
1183
	DR_DEVICE_IOREQUEST			DeviceIoRequest;
1184
	DWORD					FsInformationClass;
1185
	DWORD					Length;
1186
	BYTE					Padding[24];
1187
	BYTE *					SetVolumeBuffer;
1188
	void					(*__destructor)(struct _DR_DRIVE_SET_VOLUME_INFORMATION_REQ *);
1189
	int					(*out)(struct _DR_DRIVE_SET_VOLUME_INFORMATION_REQ *, struct stream *);
1190
	int					(*in)(struct _DR_DRIVE_SET_VOLUME_INFORMATION_REQ *, struct stream *);
1191
} DR_DRIVE_SET_VOLUME_INFORMATION_REQ;
1192
1193
typedef struct _DR_DRIVE_SET_INFORMATION_REQ {
1194
	DR_DEVICE_IOREQUEST			DeviceIoRequest;
1195
	DWORD					FsInformationClass;
1196
	DWORD					Length;
1197
	BYTE					Padding[24];
1198
	union _DrDriveSetInformationReq_Buffer {
1199
		BYTE					bytes[124];
1200
		FILE_BASIC_INFORMATION			BasicInformation, basic;
1201
		QWORD					EndOfFileInformation, eof;
1202
		BYTE					DispositionInformation, disposition;
1203
		RDP_FILE_RENAME_INFORMATION		RenameInformation, rename;
1204
		QWORD					AllocationInformation, allocation;
1205
	}					SetBuffer;
1206
	void					(*__destructor)(struct _DR_DRIVE_SET_INFORMATION_REQ *);
1207
	int					(*out)(struct _DR_DRIVE_SET_INFORMATION_REQ *, struct stream *);
1208
	int					(*in)(struct _DR_DRIVE_SET_INFORMATION_REQ *, struct stream *);
1209
1210
	#define	FileRenameInformation		0x0000000A
1211
	#define	FileDispositionInformation	0x0000000D
1212
	#define	FileAllocationInformation	0x00000013
1213
	#define	FileEndOfFileInformation	0x00000014
1214
} DR_DRIVE_SET_INFORMATION_REQ;
1215
1216
typedef struct _DR_DRIVE_QUERY_DIRECTORY_REQ {
1217
  /*									*/
1218
  /*	The server issues a query directory request on a redirected 	*/
1219
  /*	file system device. This request is used to obtain a directory	*/
1220
  /*	enumeration.							*/
1221
  /*									*/
1222
	DR_DEVICE_IOREQUEST			DeviceIoRequest;
1223
	DWORD					FsInformationClass;
1224
	BYTE					InitialQuery;
1225
	DWORD					PathLength;
1226
	BYTE					Padding[23];
1227
	BYTE					Path[512];
1228
	void					(*__destructor)(struct _DR_DRIVE_QUERY_DIRECTORY_REQ *);
1229
	int					(*out)(struct _DR_DRIVE_QUERY_DIRECTORY_REQ *, struct stream *);
1230
	int					(*in)(struct _DR_DRIVE_QUERY_DIRECTORY_REQ *, struct stream *);
1231
	int					(*setPath)(struct _DR_DRIVE_QUERY_DIRECTORY_REQ *, const char *);
1232
1233
	#define	FileDirectoryInformation	0x00000001
1234
	#define	FileFullDirectoryInformation	0x00000002
1235
	#define	FileBothDirectoryInformation	0x00000003
1236
	#define	FileNamesInformation		0x0000000C
1237
} DR_DRIVE_QUERY_DIRECTORY_REQ;
1238
1239
typedef struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ {
1240
	DR_DEVICE_IOREQUEST			DeviceIoRequest;
1241
	BYTE					WatchTree;
1242
	DWORD					CompletionFilter;
1243
	BYTE *					Padding[27];
1244
	void					(*__destructor)(struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *);
1245
	int					(*out)(struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *, struct stream *);
1246
	int					(*in)(struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *, struct stream *);
1247
1248
	#define	FILE_NOTIFY_CHANGE_FILE_NAME	0x00000001
1249
	#define	FILE_NOTIFY_CHANGE_DIR_NAME	0x00000002
1250
	#define	FILE_NOTIFY_CHANGE_ATTRIBUTES	0x00000004
1251
	#define	FILE_NOTIFY_CHANGE_SIZE		0x00000008
1252
	#define	FILE_NOTIFY_CHANGE_LAST_WRITE	0x00000010
1253
	#define	FILE_NOTIFY_CHANGE_LAST_ACCESS	0x00000020
1254
	#define	FILE_NOTIFY_CHANGE_CREATION	0x00000040
1255
	#define	FILE_NOTIFY_CHANGE_EA		0x00000080
1256
	#define	FILE_NOTIFY_CHANGE_SECURITY	0x00000100
1257
	#define	FILE_NOTIFY_CHANGE_STREAM_NAME	0x00000200
1258
	#define	FILE_NOTIFY_CHANGE_STREAM_SIZE	0x00000400
1259
	#define	FILE_NOTIFY_CHANGE_STREAM_WRITE	0x00000800
1260
} DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ;
1261
1262
typedef struct _DR_DRIVE_LOCK_REQ {
1263
	DR_DEVICE_IOREQUEST			DeviceIoRequest;
1264
	DWORD					Operation;
1265
	DWORD					F:1;
1266
/*	DWORD					Padding1;	*/
1267
	DWORD					NumLocks;
1268
	BYTE					Padding2[20];
1269
	RDP_LOCK_INFO *				Locks;
1270
	void					(*__destructor)(struct _DR_DRIVE_LOCK_REQ *);
1271
	int					(*out)(struct _DR_DRIVE_LOCK_REQ *, struct stream *);
1272
	int					(*in)(struct _DR_DRIVE_LOCK_REQ *, struct stream *);
1273
1274
	#define	RDP_LOWIO_OP_SHAREDLOCK		0x00000002
1275
	#define	RDP_LOWIO_OP_EXCLUSIVELOCK	0x00000003
1276
	#define	RDP_LOWIO_OP_UNLOCK		0x00000004
1277
	#define	RDP_LOWIO_OP_UNLOCK_MULTIPLE	0x00000005
1278
} DR_DRIVE_LOCK_REQ;
1279
1280
typedef struct _DR_DRIVE_CORE_DEVICE_IOCOMPLETION {
1281
	DR_DEVICE_IOCOMPLETION			DeviceIoResponse;
1282
	void					(*__destructor)(struct _DR_DRIVE_CORE_DEVICE_IOCOMPLETION *);
1283
	int					(*out)(struct _DR_DRIVE_CORE_DEVICE_IOCOMPLETION *, struct stream *);
1284
	int					(*in)(struct _DR_DRIVE_CORE_DEVICE_IOCOMPLETION *, struct stream *);
1285
} DR_DRIVE_CORE_DEVICE_IOCOMPLETION;
1286
1287
typedef struct _DR_DRIVE_CREATE_RSP {
1288
	DR_CREATE_RSP				DeviceCreateResponse;
1289
	void					(*__destructor)(struct _DR_DRIVE_CREATE_RSP *);
1290
	int					(*out)(struct _DR_DRIVE_CREATE_RSP *, struct stream *);
1291
	int					(*in)(struct _DR_DRIVE_CREATE_RSP *, struct stream *);
1292
} DR_DRIVE_CREATE_RSP;
1293
1294
typedef struct _DR_DRIVE_CLOSE_RSP {
1295
	DR_CLOSE_RSP				DeviceCloseResponse;
1296
	void					(*__destructor)(struct _DR_DRIVE_CLOSE_RSP *);
1297
	int					(*out)(struct _DR_DRIVE_CLOSE_RSP *, struct stream *);
1298
	int					(*in)(struct _DR_DRIVE_CLOSE_RSP *, struct stream *);
1299
} DR_DRIVE_CLOSE_RSP;
1300
1301
typedef struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP {
1302
	DR_DEVICE_IOCOMPLETION			DeviceIoReply;
1303
	DWORD					Length;
1304
	union _DrDriveQueryVolumeInformation_Buffer {
1305
	  BYTE						bytes[128];
1306
	  struct _FILE_FS_VOLUME_INFORMATION		FsVolumeInformation, vol;
1307
	  struct _FILE_FS_SIZE_INFORMATION		FsSizeInformation, size;
1308
	  struct _FILE_FS_FULL_SIZE_INFORMATION		FsFullSizeInformation, fullsize;
1309
	  struct _FILE_FS_DEVICE_INFORMATION		FsDeviceInformation, device;
1310
	  struct _FILE_FS_ATTRIBUTE_INFORMATION		FsAttributeInformation, attrs;
1311
	}					Buffer;
1312
	BYTE					Padding;
1313
	void					(*__destructor)(struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *);
1314
	int					(*out)(struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *, struct stream *);
1315
	int					(*in)(struct _DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *, struct stream *);
1316
} DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP;
1317
1318
typedef struct _DR_DRIVE_SET_VOLUME_INFORMATION_RSP {
1319
	DR_DEVICE_IOCOMPLETION			DeviceIoReply;
1320
	DWORD					Length;
1321
	void					(*__destructor)(struct _DR_DRIVE_SET_VOLUME_INFORMATION_RSP *);
1322
	int					(*out)(struct _DR_DRIVE_SET_VOLUME_INFORMATION_RSP *, struct stream *);
1323
	int					(*in)(struct _DR_DRIVE_SET_VOLUME_INFORMATION_RSP *, struct stream *);
1324
} DR_DRIVE_SET_VOLUME_INFORMATION_RSP;
1325
1326
typedef struct _DR_DRIVE_QUERY_INFORMATION_RSP {
1327
	DR_DEVICE_IOCOMPLETION			DeviceIoReply;
1328
	DWORD					Length;
1329
	union _DrDriveQueryInformationRsp_Buffer {
1330
	  BYTE						bytes[104], blob[104], data[104], raw[104], byteArray[104], binary[104];
1331
	  FILE_BASIC_INFORMATION			basic, basicInformation, FileBasicInformation;
1332
	  FILE_STANDARD_INFORMATION			standard, standardInformation, FileStandardInformation;
1333
	  FILE_ATTRIBUTE_TAG_INFORMATION		attributeInformation, AttributeTagInformation;
1334
	  FILE_ALL_INFORMATION				all, fileAllInformation;
1335
	}					Buffer;
1336
	void					(*__destructor)(struct _DR_DRIVE_QUERY_INFORMATION_RSP *);
1337
	int					(*out)(struct _DR_DRIVE_QUERY_INFORMATION_RSP *, struct stream *);
1338
	int					(*in)(struct _DR_DRIVE_QUERY_INFORMATION_RSP *, struct stream *);
1339
} DR_DRIVE_QUERY_INFORMATION_RSP;
1340
1341
typedef struct _DR_DRIVE_QUERY_DIRECTORY_RSP {
1342
	DR_DEVICE_IOCOMPLETION			DeviceIoReply;
1343
	DWORD					Length;
1344
	union {
1345
	  BYTE						bytes[MAX_STREAM], data[MAX_STREAM];
1346
	  FILE_DIRECTORY_INFORMATION			fileDirectoryInformation, directory;
1347
	  FILE_BOTH_DIR_INFORMATION			fileBothDirectoryInformation, both;
1348
	  FILE_FULL_DIR_INFORMATION			fileFullDirectoryInformation, full;
1349
	  FILE_NAME_INFORMATION				fileNameInformation, name;
1350
	  FILE_NAMES_INFORMATION			fileNamesInformation, names;
1351
	}					Buffer;
1352
	BYTE					Padding;
1353
	void					(*__destructor)(struct _DR_DRIVE_QUERY_DIRECTORY_RSP *);
1354
	int					(*out)(struct _DR_DRIVE_QUERY_DIRECTORY_RSP *, struct stream *);
1355
	int					(*in)(struct _DR_DRIVE_QUERY_DIRECTORY_RSP *, struct stream *);
1356
} DR_DRIVE_QUERY_DIRECTORY_RSP;
1357
1358
typedef struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP {
1359
	DR_DEVICE_IOCOMPLETION			DeviceIoReply;
1360
	DWORD					Length;
1361
	BYTE *					Buffer;
1362
	BYTE					Padding;
1363
	void					(*__destructor)(struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *);
1364
	int					(*out)(struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *, struct stream *);
1365
	int					(*in)(struct _DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *, struct stream *);
1366
} DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP;
1367
1368
typedef struct _DR_DRIVE_LOCK_RSP {
1369
	DR_DEVICE_IOCOMPLETION			DeviceIoReply;
1370
	BYTE					Padding[5];
1371
	void					(*__destructor)(struct _DR_DRIVE_LOCK_RSP *);
1372
	int					(*out)(struct _DR_DRIVE_LOCK_RSP *, struct stream *);
1373
	int					(*in)(struct _DR_DRIVE_LOCK_RSP *, struct stream *);
1374
} DR_DRIVE_LOCK_RSP;
1375
1376
typedef struct _DR_DRIVE_QUERY_INFORMATION_REQ {
1377
	DR_DEVICE_IOREQUEST			DeviceIoRequest;
1378
	DWORD					FsInformationClass;
1379
	DWORD					Length;
1380
	BYTE					Padding[24];
1381
	union _QueryBuffer {
1382
	  BYTE						bytes[40], blob[40], data[40], raw[40], byteArray[40], binary[40];
1383
	  FILE_BASIC_INFORMATION			basic, basicInformation, FileBasicInformation;
1384
	  FILE_STANDARD_INFORMATION			standard, standardInformation, FileStandardInformation;
1385
	  FILE_ATTRIBUTE_TAG_INFORMATION		attributeInformation, AttributeTagInformation;
1386
	}					QueryBuffer;
1387
	void					(*__destructor)(struct _DR_DRIVE_QUERY_INFORMATION_REQ *);
1388
	int					(*out)(struct _DR_DRIVE_QUERY_INFORMATION_REQ *, struct stream *);
1389
	int					(*in)(struct _DR_DRIVE_QUERY_INFORMATION_REQ *, struct stream *);
1390
1391
	#define	FileBasicInformation		0x00000004
1392
	#define	FileStandardInformation		0x00000005
1393
	#define	FileAttributeTagInformation	0x00000035
1394
} DR_DRIVE_QUERY_INFORMATION_REQ;
1395
1396
typedef struct _DR_DRIVE_SET_INFORMATION_RSP {
1397
	DR_DEVICE_IOCOMPLETION			DeviceIoReply;
1398
	DWORD					Length;
1399
	BYTE					Padding;
1400
	void					(*__destructor)(struct _DR_DRIVE_SET_INFORMATION_RSP *);
1401
	int					(*out)(struct _DR_DRIVE_SET_INFORMATION_RSP *, struct stream *);
1402
	int					(*in)(struct _DR_DRIVE_SET_INFORMATION_RSP *, struct stream *);
1403
} DR_DRIVE_SET_INFORMATION_RSP;
1404
1405
typedef union _STARTING_VCN_INPUT_BUFFER {
1406
	QWORD					Value;
1407
} STARTING_VCN_INPUT_BUFFER;
1408
1409
typedef struct _EXTENTS {
1410
	QWORD					NextVcn;
1411
	QWORD					Lcn;
1412
} EXTENTS;
1413
1414
typedef struct _RETRIEVAL_POINTERS_BUFFER {
1415
	DWORD					ExtentCount;
1416
	DWORD					Unused;
1417
	QWORD					StartingVcn;
1418
	EXTENTS *				Extents;
1419
} RETRIEVAL_POINTERS_BUFFER;
1420
1421
typedef struct _FILE_OBJECTID_BUFFER {
1422
	BYTE					ObjectId[16];
1423
	union _FILE_OBJECTID_UNION {
1424
		BYTE		bytes[48];
1425
		struct _FILE_OBJECTID_MISC {
1426
			BYTE	BirthVolumeId[16];
1427
			BYTE	BirthObjectId[16];
1428
			BYTE	DomainId[16];
1429
		} Fields;
1430
	} ExtendedInfo;
1431
} FILE_OBJECTID_BUFFER;
1432
1433
1434
/*****************************************************************************/
1435
1436
typedef struct _MINSHALL_FRENCH_SYMLINK {
1437
	char					XSym[5];
1438
	char					len[7];
1439
	char					md5sum[33];
1440
	char					target[1024];
1441
	int					(*in)(struct _MINSHALL_FRENCH_SYMLINK *, struct stream *);
1442
	int					(*out)(struct _MINSHALL_FRENCH_SYMLINK *, struct stream *);
1443
	char *					(*get)(struct _MINSHALL_FRENCH_SYMLINK *);
1444
	int					(*set)(struct _MINSHALL_FRENCH_SYMLINK *, const char *);
1445
} MINSHALL_FRENCH_SYMLINK;
1446
1447
typedef struct _INTERIX_SYMLINK {
1448
	char					magic[8];
1449
	char *					target;
1450
} INTERIX_SYMLINK;
1451
1452
typedef struct _INTERIX_DEV_FILE {
1453
	char					magic[8];
1454
	int64_t					major;
1455
	int64_t					minor;
1456
} INTERIX_DEV_FILE;
1457
1458
1459
/***/
1460
1461
typedef struct rdpdr_packet_header {
1462
	uint32_t				magic;
1463
	uint32_t				opcode;
1464
	uint32_t				size;
1465
	uint32_t				device_id;
1466
	uint32_t				fhandle;
1467
	uint32_t				uniqid;
1468
	uint32_t				crc32;
1469
} rdpdr_packet_header_t;
1470
1471
typedef struct rdpdr_packet {
1472
	uint32_t				magic;
1473
	uint32_t				opcode;
1474
	uint32_t				size;
1475
	uint32_t				device_id;
1476
	uint32_t				fhandle;
1477
	uint32_t				uniqid;
1478
	uint32_t				crc32;
1479
	uint8_t					data[0];
1480
} rdpdr_packet_t;
1481
1482
1483
typedef struct rdp_irq_data {
1484
	uint32_t		device_id;
1485
	uint8_t			type;
1486
	uint32_t		mask;
1487
	uint8_t			dtr;
1488
	uint8_t			rts;
1489
	uint8_t			cd;
1490
	uint8_t			ri;
1491
	uint32_t		mcr;
1492
	uint32_t		msr;
1493
	uint32_t		status;
1494
	uint32_t		rx_len;
1495
	uint8_t			rx_buf[0];
1496
} rdp_irq_data_t;
1497
1498
typedef struct rdpfs_buf {
1499
	uint32_t	len;
1500
	uint8_t		buf[0];
1501
} rdpfs_buf_t, * rdpfs_buf_p;
1502
1503
1504
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/drdynvc_defs.h (+267 lines)
Line 0    Link Here 
1
2
#ifndef __XRDP_DRDYNVC_DEFS_H__
3
#define __XRDP_DRDYNVC_DEFS_H__
4
5
#include <stdint.h>
6
#include "defines.h"
7
#include "ntstatus.h"
8
#include "arch.h"
9
#include "parse.h"
10
#include "trans.h"
11
#include "thread_calls.h"
12
#include "stream_list.h"
13
14
15
#if !defined(BYTE)
16
#define BYTE		uint8_t
17
#endif
18
#if !defined(WORD)
19
#define WORD		uint16_t
20
#endif
21
#if !defined(DWORD)
22
#define DWORD		uint32_t
23
#endif
24
#if !defined(QWORD)
25
#define QWORD		uint64_t
26
#endif
27
28
#if !defined(MAX_CB)
29
#define	MAX_CB		4
30
#endif
31
32
#if !defined(MAX_CHANNEL)
33
#define	MAX_CHANNEL	12
34
#endif
35
36
#define	DRDYNVC_NONE		0x00
37
#define	DRDYNVC_BYTE		0x00
38
#define	DRDYNVC_WORD		0x01
39
#define	DRDYNVC_DWORD		0x03
40
#define	DRDYNVC_DWORD_ALT	0x02
41
42
typedef struct _drdynvc_callback {
43
44
	#define	RDPEDYC_MAGIC	((DWORD)0xccabba333)
45
	DWORD		magic;
46
	DWORD		callback_index;
47
48
	DWORD		opid;		/* the opid assigned by "get_opid()" */
49
	DWORD		channel_id;
50
	DWORD		type;		/* 0 = fd; 1  = trans */
51
	tbus		fd;		/* file descriptor over which to send reply */
52
	DWORD		CompletionId;	/* the CompletionId of the RDP request corresponding to the original operation */
53
	DWORD		opcode;		/* the rdpfs (or rdpport, rdpprinter, rdpsc) opcode of the original operation */
54
	DWORD		uniqid;		/* specified by the filesystem handler per transaction */
55
	DWORD		flags;
56
	BYTE		cmd;
57
58
	DWORD		seq;
59
	DWORD		idx;
60
	DWORD		val;
61
62
	tc_t		mutex;
63
	tc_t		cv;
64
65
	struct trans *	trans;		/* trans channel (to be used instead of "fd" if type == 1) */
66
	struct _drdynvc * channel;	/* pointer to the dynamic virtual channel to which the original operation pertains */
67
68
	#define	CBFLAG_NONE		0x00000000	/* no flags are set */
69
	#define	CBFLAG_FINAL		0x00000001	/* the reply corresponds to the final (or only) step in a series */
70
	#define CBFLAG_INTERMEDIATE	0x00000002	/* the reply corresponds to an intermediate step in a series (rather than the final step) */
71
	#define	CBFLAG_USERDATA		0x00000004	/* the userdata buffer contains data */
72
	#define	CBFLAG_IOSTATUS		0x00000008	/* the IoStatus field is set */
73
	#define	CBFLAG_FUNC		0x00000010	/* the "func" field points to a valid callback function that should be invoked */
74
	#define	CBFLAG_IRQ		0x00000020	/* the current step is part of a pseudo-interrupt routine */
75
	#define	CBFLAG_MUTEX		0x00000040	/* the mutex field should be handled appropriately */
76
	#define	CBFLAG_SUPPRESS		0x00000080	/* do not transmit a reply message */
77
	#define	CBFLAG_CMD		0x00000100	/* the cmd field indicates the IOCTL command */
78
	#define	CBFLAG_MASK		0x00000200	/* the mask field contains a bitmask */
79
	
80
	DWORD		length;
81
	BYTE *		data;		/* optional extra data */
82
} callback_t;
83
84
typedef struct _drdynvc {
85
	DWORD			index;
86
	DWORD			channel_id;
87
	DWORD			dynamic_channel_index;
88
	DWORD			pid;
89
	BYTE			version;
90
	BYTE			id_length;
91
	WORD			priority0;
92
	WORD			priority1;
93
	WORD			priority3;
94
	WORD			priority4;
95
	BYTE			name[48];
96
	BYTE			initialized;
97
	BYTE			acknowledged;
98
	callback_t		callbacks[MAX_CB];
99
	DWORD			top_opid;
100
	tbus			pending_opids[MAX_CB];
101
	tbus			socket;
102
	tc_t			ilock;
103
	tc_t			icv;
104
	stream_list_t *		ihead;
105
	DWORD			ilen;
106
	DWORD			irem;
107
	unsigned char		istatus;
108
	tc_t			olock;
109
	tc_t			ocv;
110
	DWORD			olen;
111
	DWORD			orem;
112
	stream_list_t *		ohead;
113
	unsigned char		ostatus;
114
	struct trans *		ccon;
115
} drdynvc_t, rdpchan_t;
116
117
typedef struct _drdynvc_list {
118
	DWORD			ChannelCount;
119
	struct _drdynvc	**	ChannelList;
120
} drdynvc_list_t, rdpchan_list_t;
121
122
123
#define	RDPCHAN_OPEN			0x0001
124
#define	RDPCHAN_DATAFIRST		0x0002
125
#define	RDPCHAN_DATA			0x0003
126
#define	RDPCHAN_CLOSE			0x0004
127
#define RDPCHAN_CAPABILITIES		0x0005
128
#define RDPCHAN_QUERY			0x0006
129
#define RDPCHAN_ERROR			0x0010
130
131
/*****************************************************************************/
132
133
#define DRDYNVC_MAX_PDU			0x0640
134
					/* = 1600 bytes */
135
136
#define	DRDYNVC_CREATE			0x01
137
#define	DRDYNVC_DATAFIRST		0x02
138
#define	DRDYNVC_DATA			0x03
139
#define	DRDYNVC_CLOSE			0x04
140
#define	DRDYNVC_CAPABILITIES		0x05
141
142
#define DRDYNVC_VERSION1		0x0001
143
#define DRDYNVC_VERSION2		0x0002
144
145
typedef struct _DYNVC_CAPS_VERSION1_RSP {
146
	BYTE			Cmd;
147
	BYTE			Sp;
148
	BYTE			cbChId;
149
	BYTE			Pad;
150
	DWORD			Version;
151
	int			(* out)(struct _DYNVC_CAPS_VERSION1_RSP *, struct stream *);
152
	int			(* in)(struct _DYNVC_CAPS_VERSION1_RSP *, struct stream *);
153
	void			(* destroy)(struct _DYNVC_CAPS_VERSION1_RSP *);
154
} DYNVC_CAPS_VERSION1, DYNVC_CAPS_RSP;
155
156
typedef struct _DYNVC_CAPS_VERSION2 {
157
	BYTE			Cmd;
158
	BYTE			Sp;
159
	BYTE			cbChId;
160
	BYTE			Pad;
161
	DWORD			Version;
162
	WORD			PriorityCharge0;
163
	WORD			PriorityCharge1;
164
	WORD			PriorityCharge2;
165
	WORD			PriorityCharge3;
166
	int			(* out)(struct _DYNVC_CAPS_VERSION2 *, struct stream *);
167
	int			(* in)(struct _DYNVC_CAPS_VERSION2 *, struct stream *);
168
	void			(* destroy)(struct _DYNVC_CAPS_VERSION2 *);
169
} DYNVC_CAPS_VERSION2;
170
171
typedef struct _DYNVC_CREATE_REQ {
172
	BYTE			Cmd;
173
	BYTE			Pri;
174
	BYTE			cbChId;
175
	DWORD			ChannelId;
176
	int			(* out)(struct _DYNVC_CREATE_REQ *, struct stream *);
177
	int			(* in)(struct _DYNVC_CREATE_REQ *, struct stream *);
178
	void			(* destroy)(struct _DYNVC_CREATE_REQ *);
179
	BYTE			ChannelName[48];
180
} DYNVC_CREATE_REQ;
181
182
typedef struct _DYNVC_CREATE_RSP {
183
	BYTE			Cmd;
184
	BYTE			Sp;
185
	BYTE			cbChId;
186
	DWORD			ChannelId;
187
	DWORD			CreationStatus;
188
	int			(* out)(struct _DYNVC_CREATE_RSP *, struct stream *);
189
	int			(* in)(struct _DYNVC_CREATE_RSP *, struct stream *);
190
	void			(* destroy)(struct _DYNVC_CREATE_RSP *);
191
} DYNVC_CREATE_RSP;
192
193
typedef struct _DYNVC_DATA_FIRST {
194
	BYTE			Cmd;
195
	BYTE			Len;
196
	BYTE			cbChId;
197
	DWORD			ChannelId;
198
	DWORD			Length;			/*	total length of the message to be sent	*/
199
	int			(* out)(struct _DYNVC_DATA_FIRST *, struct stream *);
200
	int			(* in)(struct _DYNVC_DATA_FIRST *, struct stream *);
201
	void			(* destroy)(struct _DYNVC_DATA_FIRST *);
202
	BYTE			Data[0];		/*	the length of the data in this field is equal to 1,600 bytes minus the sum of the sizes of the previous fields	*/
203
} DYNVC_DATA_FIRST;
204
205
typedef struct _DYNVC_DATA {
206
	BYTE			Cmd;
207
	BYTE			Sp;
208
	BYTE			cbChId;
209
	DWORD			ChannelId;
210
	DWORD			Length;
211
	int			(* out)(struct _DYNVC_DATA *, struct stream *);
212
	int			(* in)(struct _DYNVC_DATA *, struct stream *);
213
	void			(* destroy)(struct _DYNVC_DATA *);
214
	BYTE			Data[0];		/*	the length of the data in this field is equal to 1,600 bytes minus the sum of the sizes of the previous fields	*/
215
} DYNVC_DATA;
216
217
typedef struct _DYNVC_CLOSE {
218
	BYTE			Cmd;
219
	BYTE			Sp;
220
	BYTE			cbChId;
221
	DWORD			ChannelId;
222
	int			(* out)(struct _DYNVC_CLOSE *, struct stream *);
223
	int			(* in)(struct _DYNVC_CLOSE *, struct stream *);
224
	void			(* destroy)(struct _DYNVC_CLOSE *);
225
} DYNVC_CLOSE;
226
227
typedef struct _DYNVC_HEADER {
228
	BYTE			Cmd;
229
	BYTE			Pri;
230
	BYTE			cbChId;
231
} DYNVC_HEADER;
232
233
typedef union _DYNVC_UNION {
234
	DYNVC_HEADER			header;
235
	DYNVC_CAPS_VERSION1		caps_version1;
236
	DYNVC_CAPS_VERSION2		caps_version2;
237
	DYNVC_CAPS_RSP			caps_rdp;
238
	DYNVC_CREATE_REQ		create_req;
239
	DYNVC_CREATE_RSP		create_rsp;
240
	DYNVC_DATA_FIRST		datafirst;
241
	DYNVC_DATA			data;
242
	DYNVC_CLOSE			close;
243
} DYNVC_ANY;
244
245
/***/
246
247
typedef struct rdpedyc_packet_header {
248
	DWORD				magic;
249
	DWORD				opcode;
250
	DWORD				size;
251
	DWORD				channel_id;
252
	DWORD				uniqid;
253
	DWORD				crc32;
254
} rdpedyc_packet_header_t;
255
256
typedef struct rdpedyc_packet {
257
	DWORD				magic;
258
	DWORD				opcode;
259
	DWORD				size;
260
	DWORD				channel_id;
261
	DWORD				uniqid;
262
	DWORD				crc32;
263
	BYTE					data[0];
264
} rdpedyc_packet_t;
265
266
267
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/Makefile.am (-4 / +33 lines)
 Lines 1-23    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED \
12
  -D_POSIX_PTHREAD_SEMATICS \
13
  -D_POSIX_PTHREADS
14
15
LDFLAGS = \
16
  -lpthread
7
17
8
lib_LTLIBRARIES = \
18
lib_LTLIBRARIES = \
9
  libcommon.la
19
  libcommon.la
10
20
11
libcommon_la_SOURCES = \
21
libcommon_la_SOURCES = \
22
  crc32.c \
23
  crc32.h \
12
  d3des.c \
24
  d3des.c \
25
  dbg.c \
13
  file.c \
26
  file.c \
14
  list.c \
27
  list.c \
15
  log.c \
28
  log.c \
16
  os_calls.c \
29
  os_calls.c \
30
  os_calls.h \
31
  rdpdr.h \
32
  rdpdr_methods.c \
33
  rdpdr_methods.h \
17
  ssl_calls.c \
34
  ssl_calls.c \
35
  stringlist.c \
18
  thread_calls.c \
36
  thread_calls.c \
19
  trans.c
37
  thread_calls.h \
38
  thread_macros.h \
39
  trans.c \
40
  trans.h \
41
  ringbuffer.c \
42
  ringbuffer.h \
43
  ntddser.h \
44
  ntstatus.h \
45
  nterrmsg.h \
46
  devredir_defs.h \
47
  drdynvc_defs.h \
48
  recording_defs.h \
49
  sound_defs.h
20
50
21
libcommon_la_LIBADD = \
51
libcommon_la_LIBADD = \
22
  -lcrypto \
52
  -lcrypto
23
  -lpthread
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/ntddser.h (+409 lines)
Line 0    Link Here 
1
/*
2
 * DDK definitions for serial port
3
 *
4
 * Copyright (C) 2006 Eric Pouech
5
 * From w32api package
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
 */
21
22
#ifndef _NTDDSER_H_
23
#define _NTDDSER_H_
24
25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28
29
#ifndef NT_IOCTLS
30
#define NT_IOCTLS
31
32
#define IOCTL_SERIAL_CLEAR_STATS                                        \
33
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 36, METHOD_BUFFERED, FILE_ANY_ACCESS)
34
#define IOCTL_SERIAL_CLR_DTR                                            \
35
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
36
#define IOCTL_SERIAL_CLR_RTS                                            \
37
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
38
#define IOCTL_SERIAL_CONFIG_SIZE                                        \
39
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 32, METHOD_BUFFERED, FILE_ANY_ACCESS)
40
#define IOCTL_SERIAL_GET_BAUD_RATE                                      \
41
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 20, METHOD_BUFFERED, FILE_ANY_ACCESS)
42
#define IOCTL_SERIAL_GET_CHARS                                          \
43
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 22, METHOD_BUFFERED, FILE_ANY_ACCESS)
44
#define IOCTL_SERIAL_GET_COMMSTATUS                                     \
45
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 27, METHOD_BUFFERED, FILE_ANY_ACCESS)
46
#define IOCTL_SERIAL_GET_DTRRTS                                         \
47
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
48
#define IOCTL_SERIAL_GET_HANDFLOW                                       \
49
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 24, METHOD_BUFFERED, FILE_ANY_ACCESS)
50
#define IOCTL_SERIAL_GET_LINE_CONTROL                                   \
51
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 21, METHOD_BUFFERED, FILE_ANY_ACCESS)
52
#define IOCTL_SERIAL_GET_MODEM_CONTROL                                  \
53
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 37, METHOD_BUFFERED, FILE_ANY_ACCESS)
54
#define IOCTL_SERIAL_GET_MODEMSTATUS                                    \
55
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 26, METHOD_BUFFERED, FILE_ANY_ACCESS)
56
#define IOCTL_SERIAL_GET_PROPERTIES                                     \
57
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 29, METHOD_BUFFERED, FILE_ANY_ACCESS)
58
#define IOCTL_SERIAL_GET_STATS                                          \
59
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 35, METHOD_BUFFERED, FILE_ANY_ACCESS)
60
#define IOCTL_SERIAL_GET_TIMEOUTS                                       \
61
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
62
#define IOCTL_SERIAL_GET_WAIT_MASK                                      \
63
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 16, METHOD_BUFFERED, FILE_ANY_ACCESS)
64
#define IOCTL_SERIAL_IMMEDIATE_CHAR                                     \
65
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
66
#ifndef IOCTL_SERIAL_LSRMST_INSERT
67
/* it's already defined in winioctl.h */
68
#define IOCTL_SERIAL_LSRMST_INSERT                             \
69
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 31, METHOD_BUFFERED, FILE_ANY_ACCESS)
70
#endif
71
#define IOCTL_SERIAL_PURGE                                              \
72
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 19, METHOD_BUFFERED, FILE_ANY_ACCESS)
73
#define IOCTL_SERIAL_RESET_DEVICE                                       \
74
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 11, METHOD_BUFFERED, FILE_ANY_ACCESS)
75
#define IOCTL_SERIAL_SET_BAUD_RATE                                      \
76
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
77
#define IOCTL_SERIAL_SET_BREAK_ON                                       \
78
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 4, METHOD_BUFFERED, FILE_ANY_ACCESS)
79
#define IOCTL_SERIAL_SET_BREAK_OFF                                      \
80
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
81
#define IOCTL_SERIAL_SET_CHARS                                          \
82
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 23, METHOD_BUFFERED, FILE_ANY_ACCESS)
83
#define IOCTL_SERIAL_SET_DTR                                            \
84
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
85
#define IOCTL_SERIAL_SET_FIFO_CONTROL                                   \
86
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 39, METHOD_BUFFERED, FILE_ANY_ACCESS)
87
#define IOCTL_SERIAL_SET_HANDFLOW                                       \
88
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 25, METHOD_BUFFERED, FILE_ANY_ACCESS)
89
#define IOCTL_SERIAL_SET_LINE_CONTROL                                   \
90
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
91
#define IOCTL_SERIAL_SET_MODEM_CONTROL                                  \
92
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 38, METHOD_BUFFERED, FILE_ANY_ACCESS)
93
#define IOCTL_SERIAL_SET_QUEUE_SIZE                                     \
94
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
95
#define IOCTL_SERIAL_SET_RTS                                            \
96
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
97
#define IOCTL_SERIAL_SET_TIMEOUTS                                       \
98
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
99
#define IOCTL_SERIAL_SET_WAIT_MASK                                      \
100
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 17, METHOD_BUFFERED, FILE_ANY_ACCESS)
101
#define IOCTL_SERIAL_SET_XOFF                                           \
102
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)
103
#define IOCTL_SERIAL_SET_XON                                            \
104
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
105
#define IOCTL_SERIAL_WAIT_ON_MASK                                       \
106
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)
107
#define IOCTL_SERIAL_XOFF_COUNTER                                       \
108
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 28, METHOD_BUFFERED, FILE_ANY_ACCESS)
109
110
#endif	/* NT_IOCTLS */
111
112
typedef unsigned long		ULONG;
113
typedef long			LONG;
114
typedef unsigned char		UCHAR;
115
typedef unsigned short		USHORT;
116
typedef short			SHORT;
117
typedef unsigned short		WCHAR;
118
typedef UCHAR			BOOLEAN;
119
120
typedef struct _SERIAL_BAUD_RATE {
121
    ULONG       BaudRate;
122
} SERIAL_BAUD_RATE, *PSERIAL_BAUD_RATE;
123
124
/* SERIAL_BAUD_RATE.BaudRate constants */
125
#define SERIAL_BAUD_075                   0x00000001
126
#define SERIAL_BAUD_110                   0x00000002
127
#define SERIAL_BAUD_134_5                 0x00000004
128
#define SERIAL_BAUD_150                   0x00000008
129
#define SERIAL_BAUD_300                   0x00000010
130
#define SERIAL_BAUD_600                   0x00000020
131
#define SERIAL_BAUD_1200                  0x00000040
132
#define SERIAL_BAUD_1800                  0x00000080
133
#define SERIAL_BAUD_2400                  0x00000100
134
#define SERIAL_BAUD_4800                  0x00000200
135
#define SERIAL_BAUD_7200                  0x00000400
136
#define SERIAL_BAUD_9600                  0x00000800
137
#define SERIAL_BAUD_14400                 0x00001000
138
#define SERIAL_BAUD_19200                 0x00002000
139
#define SERIAL_BAUD_38400                 0x00004000
140
#define SERIAL_BAUD_56K                   0x00008000
141
#define SERIAL_BAUD_128K                  0x00010000
142
#define SERIAL_BAUD_115200                0x00020000
143
#define SERIAL_BAUD_57600                 0x00040000
144
#define SERIAL_BAUD_USER                  0x10000000
145
146
typedef struct _SERIAL_CHARS
147
{
148
    UCHAR       EofChar;
149
    UCHAR       ErrorChar;
150
    UCHAR       BreakChar;
151
    UCHAR       EventChar;
152
    UCHAR       XonChar;
153
    UCHAR       XoffChar;
154
} SERIAL_CHARS, *PSERIAL_CHARS;
155
156
typedef struct _SERIAL_STATUS
157
{
158
    ULONG	Errors;
159
    ULONG	HoldReasons;
160
    ULONG	AmountInInQueue;
161
    ULONG	AmountInOutQueue;
162
    UCHAR	EofReceived;
163
    UCHAR	WaitForImmediate;
164
} SERIAL_STATUS, *PSERIAL_STATUS;
165
166
typedef struct _SERIAL_HANDFLOW
167
{
168
    ULONG       ControlHandShake;
169
    ULONG       FlowReplace;
170
    LONG        XonLimit;
171
    LONG        XoffLimit;
172
} SERIAL_HANDFLOW, *PSERIAL_HANDFLOW;
173
174
#define SERIAL_DTR_MASK                   0x00000003
175
#define SERIAL_DTR_CONTROL                0x00000001
176
#define SERIAL_DTR_HANDSHAKE              0x00000002
177
#define SERIAL_CTS_HANDSHAKE              0x00000008
178
#define SERIAL_DSR_HANDSHAKE              0x00000010
179
#define SERIAL_DCD_HANDSHAKE              0x00000020
180
#define SERIAL_OUT_HANDSHAKEMASK          0x00000038
181
#define SERIAL_DSR_SENSITIVITY            0x00000040
182
#define SERIAL_ERROR_ABORT                0x80000000
183
#define SERIAL_CONTROL_INVALID            0x7fffff84
184
#define SERIAL_AUTO_TRANSMIT              0x00000001
185
#define SERIAL_AUTO_RECEIVE               0x00000002
186
#define SERIAL_ERROR_CHAR                 0x00000004
187
#define SERIAL_NULL_STRIPPING             0x00000008
188
#define SERIAL_BREAK_CHAR                 0x00000010
189
#define SERIAL_RTS_MASK                   0x000000c0
190
#define SERIAL_RTS_CONTROL                0x00000040
191
#define SERIAL_RTS_HANDSHAKE              0x00000080
192
#define SERIAL_TRANSMIT_TOGGLE            0x000000c0
193
#define SERIAL_XOFF_CONTINUE              0x80000000
194
#define SERIAL_FLOW_INVALID               0x7fffff20
195
196
typedef struct _SERIAL_LINE_CONTROL {
197
    UCHAR       StopBits;
198
    UCHAR       Parity;
199
    UCHAR       WordLength;
200
} SERIAL_LINE_CONTROL, *PSERIAL_LINE_CONTROL;
201
202
/* SERIAL_LINE_CONTROL.StopBits constants */
203
#define STOP_BIT_1                        0x00
204
#define STOP_BITS_1_5                     0x01
205
#define STOP_BITS_2                       0x02
206
207
/* SERIAL_LINE_CONTROL.Parity constants */
208
#define NO_PARITY                         0x00
209
#define ODD_PARITY                        0x01
210
#define EVEN_PARITY                       0x02
211
#define MARK_PARITY                       0x03
212
#define SPACE_PARITY                      0x04
213
214
/* IOCTL_SERIAL_(GET_MODEM_CONTROL, SET_MODEM_CONTROL) flags */
215
#define SERIAL_IOC_MCR_DTR                0x00000001
216
#define SERIAL_IOC_MCR_RTS                0x00000002
217
#define SERIAL_IOC_MCR_OUT1               0x00000004
218
#define SERIAL_IOC_MCR_OUT2               0x00000008
219
#define SERIAL_IOC_MCR_LOOP               0x00000010
220
221
typedef struct _SERIAL_COMMPROP
222
{
223
    USHORT      PacketLength;
224
    USHORT      PacketVersion;
225
    ULONG       ServiceMask;
226
    ULONG       Reserved1;
227
    ULONG       MaxTxQueue;
228
    ULONG       MaxRxQueue;
229
    ULONG       MaxBaud;
230
    ULONG       ProvSubType;
231
    ULONG       ProvCapabilities;
232
    ULONG       SettableParams;
233
    ULONG       SettableBaud;
234
    USHORT      SettableData;
235
    USHORT      SettableStopParity;
236
    ULONG       CurrentTxQueue;
237
    ULONG       CurrentRxQueue;
238
    ULONG       ProvSpec1;
239
    ULONG       ProvSpec2;
240
    WCHAR       ProvChar[1];
241
} SERIAL_COMMPROP, *PSERIAL_COMMPROP;
242
243
/* SERIAL_COMMPROP.SettableParams flags */
244
#define SERIAL_SP_PARITY                  0x0001
245
#define SERIAL_SP_BAUD                    0x0002
246
#define SERIAL_SP_DATABITS                0x0004
247
#define SERIAL_SP_STOPBITS                0x0008
248
#define SERIAL_SP_HANDSHAKING             0x0010
249
#define SERIAL_SP_PARITY_CHECK            0x0020
250
#define SERIAL_SP_CARRIER_DETECT          0x0040
251
252
/* SERIAL_COMMPROP.ProvCapabilities flags */
253
#define SERIAL_PCF_DTRDSR                 0x00000001
254
#define SERIAL_PCF_RTSCTS                 0x00000002
255
#define SERIAL_PCF_CD                     0x00000004
256
#define SERIAL_PCF_PARITY_CHECK           0x00000008
257
#define SERIAL_PCF_XONXOFF                0x00000010
258
#define SERIAL_PCF_SETXCHAR               0x00000020
259
#define SERIAL_PCF_TOTALTIMEOUTS          0x00000040
260
#define SERIAL_PCF_INTTIMEOUTS            0x00000080
261
#define SERIAL_PCF_SPECIALCHARS           0x00000100
262
#define SERIAL_PCF_16BITMODE              0x00000200
263
264
/* SERIAL_COMMPROP.SettableData flags */
265
#define SERIAL_DATABITS_5                 0x0001
266
#define SERIAL_DATABITS_6                 0x0002
267
#define SERIAL_DATABITS_7                 0x0004
268
#define SERIAL_DATABITS_8                 0x0008
269
#define SERIAL_DATABITS_16                0x0010
270
#define SERIAL_DATABITS_16X               0x0020
271
272
/* SERIAL_COMMPROP.SettableStopParity flags */
273
#define SERIAL_STOPBITS_10                0x0001
274
#define SERIAL_STOPBITS_15                0x0002
275
#define SERIAL_STOPBITS_20                0x0004
276
#define SERIAL_PARITY_NONE                0x0100
277
#define SERIAL_PARITY_ODD                 0x0200
278
#define SERIAL_PARITY_EVEN                0x0400
279
#define SERIAL_PARITY_MARK                0x0800
280
#define SERIAL_PARITY_SPACE               0x1000
281
282
typedef struct _SERIALPERF_STATS
283
{
284
    ULONG       ReceivedCount;
285
    ULONG       TransmittedCount;
286
    ULONG       FrameErrorCount;
287
    ULONG       SerialOverrunErrorCount;
288
    ULONG       BufferOverrunErrorCount;
289
    ULONG       ParityErrorCount;
290
} SERIALPERF_STATS, *PSERIALPERF_STATS;
291
292
typedef struct _SERIAL_TIMEOUTS
293
{
294
    ULONG       ReadIntervalTimeout;
295
    ULONG       ReadTotalTimeoutMultiplier;
296
    ULONG       ReadTotalTimeoutConstant;
297
    ULONG       WriteTotalTimeoutMultiplier;
298
    ULONG       WriteTotalTimeoutConstant;
299
} SERIAL_TIMEOUTS, *PSERIAL_TIMEOUTS;
300
301
/* IOCTL_SERIAL_(GET_WAIT_MASK, SET_WAIT_MASK, WAIT_ON_MASK) flags */
302
#define SERIAL_EV_RXCHAR                  0x0001
303
#define SERIAL_EV_RXFLAG                  0x0002
304
#define SERIAL_EV_TXEMPTY                 0x0004
305
#define SERIAL_EV_CTS                     0x0008
306
#define SERIAL_EV_DSR                     0x0010
307
#define SERIAL_EV_RLSD                    0x0020
308
#define SERIAL_EV_BREAK                   0x0040
309
#define SERIAL_EV_ERR                     0x0080
310
#define SERIAL_EV_RING                    0x0100
311
#define SERIAL_EV_PERR                    0x0200
312
#define SERIAL_EV_RX80FULL                0x0400
313
#define SERIAL_EV_EVENT1                  0x0800
314
#define SERIAL_EV_EVENT2                  0x1000
315
316
/* IOCTL_SERIAL_LSRMST_INSERT constants */
317
#define SERIAL_LSRMST_LSR_DATA            0x01
318
#define SERIAL_LSRMST_LSR_NODATA          0x02
319
#define SERIAL_LSRMST_MST                 0x03
320
#define SERIAL_LSRMST_ESCAPE              0x00
321
322
/* IOCTL_SERIAL_PURGE constants */
323
#define SERIAL_PURGE_TXABORT              0x00000001
324
#define SERIAL_PURGE_RXABORT              0x00000002
325
#define SERIAL_PURGE_TXCLEAR              0x00000004
326
#define SERIAL_PURGE_RXCLEAR              0x00000008
327
328
/* IOCTL_SERIAL_SET_FIFO_CONTROL constants */
329
#define SERIAL_IOC_FCR_FIFO_ENABLE        0x00000001
330
#define SERIAL_IOC_FCR_RCVR_RESET         0x00000002
331
#define SERIAL_IOC_FCR_XMIT_RESET         0x00000004
332
#define SERIAL_IOC_FCR_DMA_MODE           0x00000008
333
#define SERIAL_IOC_FCR_RES1               0x00000010
334
#define SERIAL_IOC_FCR_RES2               0x00000020
335
#define SERIAL_IOC_FCR_RCVR_TRIGGER_LSB   0x00000040
336
#define SERIAL_IOC_FCR_RCVR_TRIGGER_MSB   0x00000080
337
338
typedef struct _SERIAL_QUEUE_SIZE
339
{
340
    ULONG       InSize;
341
    ULONG       OutSize;
342
} SERIAL_QUEUE_SIZE, *PSERIAL_QUEUE_SIZE;
343
344
typedef struct _SERIAL_XOFF_COUNTER
345
{
346
    ULONG       Timeout;
347
    LONG        Counter;
348
    UCHAR       XoffChar;
349
} SERIAL_XOFF_COUNTER, *PSERIAL_XOFF_COUNTER;
350
351
typedef struct _SERIAL_BASIC_SETTINGS
352
{
353
    SERIAL_TIMEOUTS     Timeouts;
354
    SERIAL_HANDFLOW     HandFlow;
355
    ULONG       RxFifo;
356
    ULONG       TxFifo;
357
} SERIAL_BASIC_SETTINGS, *PSERIAL_BASIC_SETTINGS;
358
359
#define SERIAL_ERROR_BREAK                0x00000001
360
#define SERIAL_ERROR_FRAMING              0x00000002
361
#define SERIAL_ERROR_OVERRUN              0x00000004
362
#define SERIAL_ERROR_QUEUEOVERRUN         0x00000008
363
#define SERIAL_ERROR_PARITY               0x00000010
364
365
#define SERIAL_SP_UNSPECIFIED             0x00000000
366
#define SERIAL_SP_RS232                   0x00000001
367
#define SERIAL_SP_PARALLEL                0x00000002
368
#define SERIAL_SP_RS422                   0x00000003
369
#define SERIAL_SP_RS423                   0x00000004
370
#define SERIAL_SP_RS449                   0x00000005
371
#define SERIAL_SP_MODEM                   0X00000006
372
#define SERIAL_SP_FAX                     0x00000021
373
#define SERIAL_SP_SCANNER                 0x00000022
374
#define SERIAL_SP_BRIDGE                  0x00000100
375
#define SERIAL_SP_LAT                     0x00000101
376
#define SERIAL_SP_TELNET                  0x00000102
377
#define SERIAL_SP_X25                     0x00000103
378
#define SERIAL_SP_SERIALCOMM              0x00000001
379
380
#define SERIAL_TX_WAITING_FOR_CTS         0x00000001
381
#define SERIAL_TX_WAITING_FOR_DSR         0x00000002
382
#define SERIAL_TX_WAITING_FOR_DCD         0x00000004
383
#define SERIAL_TX_WAITING_FOR_XON         0x00000008
384
#define SERIAL_TX_WAITING_XOFF_SENT       0x00000010
385
#define SERIAL_TX_WAITING_ON_BREAK        0x00000020
386
#define SERIAL_RX_WAITING_FOR_DSR         0x00000040
387
388
#define SERIAL_DTR_STATE                  0x00000001
389
#define SERIAL_RTS_STATE                  0x00000002
390
#define SERIAL_CTS_STATE                  0x00000010
391
#define SERIAL_DSR_STATE                  0x00000020
392
#define SERIAL_RI_STATE                   0x00000040
393
#define SERIAL_DCD_STATE                  0x00000080
394
395
typedef struct _SERIALCONFIG
396
{
397
    ULONG       Size;
398
    USHORT      Version;
399
    ULONG       SubType;
400
    ULONG       ProvOffset;
401
    ULONG       ProviderSize;
402
    WCHAR       ProviderData[1];
403
} SERIALCONFIG,*PSERIALCONFIG;
404
405
#ifdef __cplusplus
406
}
407
#endif
408
409
#endif /* _NTDDSER_H_ */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/nterrmsg.h (+925 lines)
Line 0    Link Here 
1
#if !defined(__XRDP_NT_ERR_MSG__)
2
#define __XRDP_NT_ERR_MSG__
3
4
#include <stdint.h>
5
6
typedef struct nterr_msg {
7
	uint32_t			ntstatus;
8
	const char			msg[48];
9
} nterr_msg_t;
10
11
#define NTERRMSG_ARRAY		{	\
12
  {0xC0000001, "UNSUCCESSFUL"}, \
13
  {0xC0000002, "NOT IMPLEMENTED"}, \
14
  {0xC0000003, "INVALID INFO CLASS"}, \
15
  {0xC0000004, "INFO LENGTH MISMATCH"}, \
16
  {0xC0000005, "ACCESS VIOLATION"}, \
17
  {0xC0000006, "IN PAGE ERROR"}, \
18
  {0xC0000007, "PAGEFILE QUOTA"}, \
19
  {0xC0000008, "INVALID HANDLE"}, \
20
  {0xC0000009, "BAD INITIAL STACK"}, \
21
  {0xC000000A, "BAD INITIAL PC"}, \
22
  {0xC000000B, "INVALID CID"}, \
23
  {0xC000000C, "TIMER NOT CANCELED"}, \
24
  {0xC000000D, "INVALID PARAMETER"}, \
25
  {0xC000000E, "NO SUCH DEVICE"}, \
26
  {0xC000000F, "NO SUCH FILE"}, \
27
  {0xC0000010, "INVALID DEVICE REQUEST"}, \
28
  {0xC0000011, "END OF FILE"}, \
29
  {0xC0000012, "WRONG VOLUME"}, \
30
  {0xC0000013, "NO MEDIA IN DEVICE"}, \
31
  {0xC0000014, "UNRECOGNIZED MEDIA"}, \
32
  {0xC0000015, "NONEXISTENT SECTOR"}, \
33
  {0xC0000016, "MORE PROCESSING REQUIRED"}, \
34
  {0xC0000017, "NO MEMORY"}, \
35
  {0xC0000018, "CONFLICTING ADDRESSES"}, \
36
  {0xC0000019, "NOT MAPPED VIEW"}, \
37
  {0xC000001A, "UNABLE TO FREE VM"}, \
38
  {0xC000001B, "UNABLE TO DELETE SECTION"}, \
39
  {0xC000001C, "INVALID SYSTEM SERVICE"}, \
40
  {0xC000001D, "ILLEGAL INSTRUCTION"}, \
41
  {0xC000001E, "INVALID LOCK SEQUENCE"}, \
42
  {0xC000001F, "INVALID VIEW SIZE"}, \
43
  {0xC0000020, "INVALID FILE FOR SECTION"}, \
44
  {0xC0000021, "ALREADY COMMITTED"}, \
45
  {0xC0000022, "ACCESS DENIED"}, \
46
  {0xC0000023, "BUFFER TOO SMALL"}, \
47
  {0xC0000024, "OBJECT TYPE MISMATCH"}, \
48
  {0xC0000025, "NONCONTINUABLE EXCEPTION"}, \
49
  {0xC0000026, "INVALID DISPOSITION"}, \
50
  {0xC0000027, "UNWIND"}, \
51
  {0xC0000028, "BAD STACK"}, \
52
  {0xC0000029, "INVALID UNWIND TARGET"}, \
53
  {0xC000002A, "NOT LOCKED"}, \
54
  {0xC000002B, "PARITY ERROR"}, \
55
  {0xC000002C, "UNABLE TO DECOMMIT VM"}, \
56
  {0xC000002D, "NOT COMMITTED"}, \
57
  {0xC000002E, "INVALID PORT ATTRIBUTES"}, \
58
  {0xC000002F, "PORT MESSAGE TOO LONG"}, \
59
  {0xC0000030, "INVALID PARAMETER MIX"}, \
60
  {0xC0000031, "INVALID QUOTA LOWER"}, \
61
  {0xC0000032, "DISK CORRUPT ERROR"}, \
62
  {0xC0000033, "OBJECT NAME INVALID"}, \
63
  {0xC0000034, "OBJECT NAME NOT FOUND"}, \
64
  {0xC0000035, "OBJECT NAME COLLISION"}, \
65
  {0xC0000037, "PORT DISCONNECTED"}, \
66
  {0xC0000038, "DEVICE ALREADY ATTACHED"}, \
67
  {0xC0000039, "OBJECT PATH INVALID"}, \
68
  {0xC000003A, "OBJECT PATH NOT FOUND"}, \
69
  {0xC000003B, "OBJECT PATH SYNTAX BAD"}, \
70
  {0xC000003C, "DATA OVERRUN"}, \
71
  {0xC000003D, "DATA LATE ERROR"}, \
72
  {0xC000003E, "DATA ERROR"}, \
73
  {0xC000003F, "CRC ERROR"}, \
74
  {0xC0000040, "SECTION TOO BIG"}, \
75
  {0xC0000041, "PORT CONNECTION REFUSED"}, \
76
  {0xC0000042, "INVALID PORT HANDLE"}, \
77
  {0xC0000043, "SHARING VIOLATION"}, \
78
  {0xC0000044, "QUOTA EXCEEDED"}, \
79
  {0xC0000045, "INVALID PAGE PROTECTION"}, \
80
  {0xC0000046, "MUTANT NOT OWNED"}, \
81
  {0xC0000047, "SEMAPHORE LIMIT EXCEEDED"}, \
82
  {0xC0000048, "PORT ALREADY SET"}, \
83
  {0xC0000049, "SECTION NOT IMAGE"}, \
84
  {0xC000004A, "SUSPEND COUNT EXCEEDED"}, \
85
  {0xC000004B, "THREAD IS TERMINATING"}, \
86
  {0xC000004C, "BAD WORKING SET LIMIT"}, \
87
  {0xC000004D, "INCOMPATIBLE FILE MAP"}, \
88
  {0xC000004E, "SECTION PROTECTION"}, \
89
  {0xC000004F, "EAS NOT SUPPORTED"}, \
90
  {0xC0000050, "EA TOO LARGE"}, \
91
  {0xC0000051, "NONEXISTENT EA ENTRY"}, \
92
  {0xC0000052, "NO EAS ON FILE"}, \
93
  {0xC0000053, "EA CORRUPT ERROR"}, \
94
  {0xC0000054, "FILE LOCK CONFLICT"}, \
95
  {0xC0000055, "LOCK NOT GRANTED"}, \
96
  {0xC0000056, "DELETE PENDING"}, \
97
  {0xC0000057, "CTL FILE NOT SUPPORTED"}, \
98
  {0xC0000058, "UNKNOWN REVISION"}, \
99
  {0xC0000059, "REVISION MISMATCH"}, \
100
  {0xC000005A, "INVALID OWNER"}, \
101
  {0xC000005B, "INVALID PRIMARY GROUP"}, \
102
  {0xC000005C, "NO IMPERSONATION TOKEN"}, \
103
  {0xC000005D, "CANT DISABLE MANDATORY"}, \
104
  {0xC000005E, "NO LOGON SERVERS"}, \
105
  {0xC000005F, "NO SUCH LOGON SESSION"}, \
106
  {0xC0000060, "NO SUCH PRIVILEGE"}, \
107
  {0xC0000061, "PRIVILEGE NOT HELD"}, \
108
  {0xC0000062, "INVALID ACCOUNT NAME"}, \
109
  {0xC0000063, "USER EXISTS"}, \
110
  {0xC0000064, "NO SUCH USER"}, \
111
  {0xC0000065, "GROUP EXISTS"}, \
112
  {0xC0000066, "NO SUCH GROUP"}, \
113
  {0xC0000067, "MEMBER IN GROUP"}, \
114
  {0xC0000068, "MEMBER NOT IN GROUP"}, \
115
  {0xC0000069, "LAST ADMIN"}, \
116
  {0xC000006A, "WRONG PASSWORD"}, \
117
  {0xC000006B, "ILL FORMED PASSWORD"}, \
118
  {0xC000006C, "PASSWORD RESTRICTION"}, \
119
  {0xC000006D, "LOGON FAILURE"}, \
120
  {0xC000006E, "ACCOUNT RESTRICTION"}, \
121
  {0xC000006F, "INVALID LOGON HOURS"}, \
122
  {0xC0000070, "INVALID WORKSTATION"}, \
123
  {0xC0000071, "PASSWORD EXPIRED"}, \
124
  {0xC0000072, "ACCOUNT DISABLED"}, \
125
  {0xC0000073, "NONE MAPPED"}, \
126
  {0xC0000074, "TOO MANY LUIDS REQUESTED"}, \
127
  {0xC0000075, "LUIDS EXHAUSTED"}, \
128
  {0xC0000076, "INVALID SUB AUTHORITY"}, \
129
  {0xC0000077, "INVALID ACL"}, \
130
  {0xC0000078, "INVALID SID"}, \
131
  {0xC0000079, "INVALID SECURITY DESCR"}, \
132
  {0xC000007A, "PROCEDURE NOT FOUND"}, \
133
  {0xC000007B, "INVALID IMAGE FORMAT"}, \
134
  {0xC000007C, "NO TOKEN"}, \
135
  {0xC000007D, "BAD INHERITANCE ACL"}, \
136
  {0xC000007E, "RANGE NOT LOCKED"}, \
137
  {0xC000007F, "DISK FULL"}, \
138
  {0xC0000080, "SERVER DISABLED"}, \
139
  {0xC0000081, "SERVER NOT DISABLED"}, \
140
  {0xC0000082, "TOO MANY GUIDS REQUESTED"}, \
141
  {0xC0000083, "GUIDS EXHAUSTED"}, \
142
  {0xC0000084, "INVALID ID AUTHORITY"}, \
143
  {0xC0000085, "AGENTS EXHAUSTED"}, \
144
  {0xC0000086, "INVALID VOLUME LABEL"}, \
145
  {0xC0000087, "SECTION NOT EXTENDED"}, \
146
  {0xC0000088, "NOT MAPPED DATA"}, \
147
  {0xC0000089, "RESOURCE DATA NOT FOUND"}, \
148
  {0xC000008A, "RESOURCE TYPE NOT FOUND"}, \
149
  {0xC000008B, "RESOURCE NAME NOT FOUND"}, \
150
  {0xC000008C, "ARRAY BOUNDS EXCEEDED"}, \
151
  {0xC000008D, "FLOAT DENORMAL OPERAND"}, \
152
  {0xC000008E, "FLOAT DIVIDE BY ZERO"}, \
153
  {0xC000008F, "FLOAT INEXACT RESULT"}, \
154
  {0xC0000090, "FLOAT INVALID OPERATION"}, \
155
  {0xC0000091, "FLOAT OVERFLOW"}, \
156
  {0xC0000092, "FLOAT STACK CHECK"}, \
157
  {0xC0000093, "FLOAT UNDERFLOW"}, \
158
  {0xC0000094, "INTEGER DIVIDE BY ZERO"}, \
159
  {0xC0000095, "INTEGER OVERFLOW"}, \
160
  {0xC0000096, "PRIVILEGED INSTRUCTION"}, \
161
  {0xC0000097, "TOO MANY PAGING FILES"}, \
162
  {0xC0000098, "FILE INVALID"}, \
163
  {0xC0000099, "ALLOTTED SPACE EXCEEDED"}, \
164
  {0xC000009A, "INSUFFICIENT RESOURCES"}, \
165
  {0xC000009B, "DFS EXIT PATH FOUND"}, \
166
  {0xC000009C, "DEVICE DATA ERROR"}, \
167
  {0xC000009D, "DEVICE NOT CONNECTED"}, \
168
  {0xC000009E, "DEVICE POWER FAILURE"}, \
169
  {0xC000009F, "FREE VM NOT AT BASE"}, \
170
  {0xC00000A0, "MEMORY NOT ALLOCATED"}, \
171
  {0xC00000A1, "WORKING SET QUOTA"}, \
172
  {0xC00000A2, "MEDIA WRITE PROTECTED"}, \
173
  {0xC00000A3, "DEVICE NOT READY"}, \
174
  {0xC00000A4, "INVALID GROUP ATTRIBUTES"}, \
175
  {0xC00000A5, "BAD IMPERSONATION LEVEL"}, \
176
  {0xC00000A6, "CANT OPEN ANONYMOUS"}, \
177
  {0xC00000A7, "BAD VALIDATION CLASS"}, \
178
  {0xC00000A8, "BAD TOKEN TYPE"}, \
179
  {0xC00000A9, "BAD MASTER BOOT RECORD"}, \
180
  {0xC00000AA, "INSTRUCTION MISALIGNMENT"}, \
181
  {0xC00000AB, "INSTANCE NOT AVAILABLE"}, \
182
  {0xC00000AC, "PIPE NOT AVAILABLE"}, \
183
  {0xC00000AD, "INVALID PIPE STATE"}, \
184
  {0xC00000AE, "PIPE BUSY"}, \
185
  {0xC00000AF, "ILLEGAL FUNCTION"}, \
186
  {0xC00000B0, "PIPE DISCONNECTED"}, \
187
  {0xC00000B1, "PIPE CLOSING"}, \
188
  {0xC00000B2, "PIPE CONNECTED"}, \
189
  {0xC00000B3, "PIPE LISTENING"}, \
190
  {0xC00000B4, "INVALID READ MODE"}, \
191
  {0xC00000B5, "IO TIMEOUT"}, \
192
  {0xC00000B6, "FILE FORCED CLOSED"}, \
193
  {0xC00000B7, "PROFILING NOT STARTED"}, \
194
  {0xC00000B8, "PROFILING NOT STOPPED"}, \
195
  {0xC00000B9, "COULD NOT INTERPRET"}, \
196
  {0xC00000BA, "FILE IS A DIRECTORY"}, \
197
  {0xC00000BB, "NOT SUPPORTED"}, \
198
  {0xC00000BC, "REMOTE NOT LISTENING"}, \
199
  {0xC00000BD, "DUPLICATE NAME"}, \
200
  {0xC00000BE, "BAD NETWORK PATH"}, \
201
  {0xC00000BF, "NETWORK BUSY"}, \
202
  {0xC00000C0, "DEVICE DOES NOT EXIST"}, \
203
  {0xC00000C1, "TOO MANY COMMANDS"}, \
204
  {0xC00000C2, "ADAPTER HARDWARE ERROR"}, \
205
  {0xC00000C3, "INVALID NETWORK RESPONSE"}, \
206
  {0xC00000C4, "UNEXPECTED NETWORK ERROR"}, \
207
  {0xC00000C5, "BAD REMOTE ADAPTER"}, \
208
  {0xC00000C6, "PRINT QUEUE FULL"}, \
209
  {0xC00000C7, "NO SPOOL SPACE"}, \
210
  {0xC00000C8, "PRINT CANCELLED"}, \
211
  {0xC00000C9, "NETWORK NAME DELETED"}, \
212
  {0xC00000CA, "NETWORK ACCESS DENIED"}, \
213
  {0xC00000CB, "BAD DEVICE TYPE"}, \
214
  {0xC00000CC, "BAD NETWORK NAME"}, \
215
  {0xC00000CD, "TOO MANY NAMES"}, \
216
  {0xC00000CE, "TOO MANY SESSIONS"}, \
217
  {0xC00000CF, "SHARING PAUSED"}, \
218
  {0xC00000D0, "REQUEST NOT ACCEPTED"}, \
219
  {0xC00000D1, "REDIRECTOR PAUSED"}, \
220
  {0xC00000D2, "NET WRITE FAULT"}, \
221
  {0xC00000D3, "PROFILING AT LIMIT"}, \
222
  {0xC00000D4, "NOT SAME DEVICE"}, \
223
  {0xC00000D5, "FILE RENAMED"}, \
224
  {0xC00000D6, "VIRTUAL CIRCUIT CLOSED"}, \
225
  {0xC00000D7, "NO SECURITY ON OBJECT"}, \
226
  {0xC00000D8, "CANT WAIT"}, \
227
  {0xC00000D9, "PIPE EMPTY"}, \
228
  {0xC00000DA, "CANT ACCESS DOMAIN INFO"}, \
229
  {0xC00000DB, "CANT TERMINATE SELF"}, \
230
  {0xC00000DC, "INVALID SERVER STATE"}, \
231
  {0xC00000DD, "INVALID DOMAIN STATE"}, \
232
  {0xC00000DE, "INVALID DOMAIN ROLE"}, \
233
  {0xC00000DF, "NO SUCH DOMAIN"}, \
234
  {0xC00000E0, "DOMAIN EXISTS"}, \
235
  {0xC00000E1, "DOMAIN LIMIT EXCEEDED"}, \
236
  {0xC00000E2, "OPLOCK NOT GRANTED"}, \
237
  {0xC00000E3, "INVALID OPLOCK PROTOCOL"}, \
238
  {0xC00000E4, "INTERNAL DB CORRUPTION"}, \
239
  {0xC00000E5, "INTERNAL ERROR"}, \
240
  {0xC00000E6, "GENERIC NOT MAPPED"}, \
241
  {0xC00000E7, "BAD DESCRIPTOR FORMAT"}, \
242
  {0xC00000E8, "INVALID USER BUFFER"}, \
243
  {0xC00000E9, "UNEXPECTED IO ERROR"}, \
244
  {0xC00000EA, "UNEXPECTED MM CREATE ERR"}, \
245
  {0xC00000EB, "UNEXPECTED MM MAP ERROR"}, \
246
  {0xC00000EC, "UNEXPECTED MM EXTEND ERR"}, \
247
  {0xC00000ED, "NOT LOGON PROCESS"}, \
248
  {0xC00000EE, "LOGON SESSION EXISTS"}, \
249
  {0xC00000EF, "INVALID PARAMETER 1"}, \
250
  {0xC00000F0, "INVALID PARAMETER 2"}, \
251
  {0xC00000F1, "INVALID PARAMETER 3"}, \
252
  {0xC00000F2, "INVALID PARAMETER 4"}, \
253
  {0xC00000F3, "INVALID PARAMETER 5"}, \
254
  {0xC00000F4, "INVALID PARAMETER 6"}, \
255
  {0xC00000F5, "INVALID PARAMETER 7"}, \
256
  {0xC00000F6, "INVALID PARAMETER 8"}, \
257
  {0xC00000F7, "INVALID PARAMETER 9"}, \
258
  {0xC00000F8, "INVALID PARAMETER 10"}, \
259
  {0xC00000F9, "INVALID PARAMETER 11"}, \
260
  {0xC00000FA, "INVALID PARAMETER 12"}, \
261
  {0xC00000FB, "REDIRECTOR NOT STARTED"}, \
262
  {0xC00000FC, "REDIRECTOR STARTED"}, \
263
  {0xC00000FD, "STACK OVERFLOW"}, \
264
  {0xC00000FE, "NO SUCH PACKAGE"}, \
265
  {0xC00000FF, "BAD FUNCTION TABLE"}, \
266
  {0xC0000100, "VARIABLE NOT FOUND"}, \
267
  {0xC0000101, "DIRECTORY NOT EMPTY"}, \
268
  {0xC0000102, "FILE CORRUPT ERROR"}, \
269
  {0xC0000103, "NOT A DIRECTORY"}, \
270
  {0xC0000104, "BAD LOGON SESSION STATE"}, \
271
  {0xC0000105, "LOGON SESSION COLLISION"}, \
272
  {0xC0000106, "NAME TOO LONG"}, \
273
  {0xC0000107, "FILES OPEN"}, \
274
  {0xC0000108, "CONNECTION IN USE"}, \
275
  {0xC0000109, "MESSAGE NOT FOUND"}, \
276
  {0xC000010A, "PROCESS IS TERMINATING"}, \
277
  {0xC000010B, "INVALID LOGON TYPE"}, \
278
  {0xC000010C, "NO GUID TRANSLATION"}, \
279
  {0xC000010D, "CANNOT IMPERSONATE"}, \
280
  {0xC000010E, "IMAGE ALREADY LOADED"}, \
281
  {0xC000010F, "ABIOS NOT PRESENT"}, \
282
  {0xC0000110, "ABIOS LID NOT EXIST"}, \
283
  {0xC0000111, "ABIOS LID ALREADY OWNED"}, \
284
  {0xC0000112, "ABIOS NOT LID OWNER"}, \
285
  {0xC0000113, "ABIOS INVALID COMMAND"}, \
286
  {0xC0000114, "ABIOS INVALID LID"}, \
287
  {0xC0000115, "ABIOS SELECTOR NOT AVAILABLE"}, \
288
  {0xC0000116, "ABIOS INVALID SELECTOR"}, \
289
  {0xC0000117, "NO LDT"}, \
290
  {0xC0000118, "INVALID LDT SIZE"}, \
291
  {0xC0000119, "INVALID LDT OFFSET"}, \
292
  {0xC000011A, "INVALID LDT DESCRIPTOR"}, \
293
  {0xC000011B, "INVALID IMAGE NE FORMAT"}, \
294
  {0xC000011C, "RXACT INVALID STATE"}, \
295
  {0xC000011D, "RXACT COMMIT FAILURE"}, \
296
  {0xC000011E, "MAPPED FILE SIZE ZERO"}, \
297
  {0xC000011F, "TOO MANY OPENED FILES"}, \
298
  {0xC0000120, "CANCELLED"}, \
299
  {0xC0000121, "CANNOT DELETE"}, \
300
  {0xC0000122, "INVALID COMPUTER NAME"}, \
301
  {0xC0000123, "FILE DELETED"}, \
302
  {0xC0000124, "SPECIAL ACCOUNT"}, \
303
  {0xC0000125, "SPECIAL GROUP"}, \
304
  {0xC0000126, "SPECIAL USER"}, \
305
  {0xC0000127, "MEMBERS PRIMARY GROUP"}, \
306
  {0xC0000128, "FILE CLOSED"}, \
307
  {0xC0000129, "TOO MANY THREADS"}, \
308
  {0xC000012A, "THREAD NOT IN PROCESS"}, \
309
  {0xC000012B, "TOKEN ALREADY IN USE"}, \
310
  {0xC000012C, "PAGEFILE QUOTA EXCEEDED"}, \
311
  {0xC000012D, "COMMITMENT LIMIT"}, \
312
  {0xC000012E, "INVALID IMAGE LE FORMAT"}, \
313
  {0xC000012F, "INVALID IMAGE NOT MZ"}, \
314
  {0xC0000130, "INVALID IMAGE PROTECT"}, \
315
  {0xC0000131, "INVALID IMAGE WIN 16"}, \
316
  {0xC0000132, "LOGON SERVER CONFLICT"}, \
317
  {0xC0000133, "TIME DIFFERENCE AT DC"}, \
318
  {0xC0000134, "SYNCHRONIZATION REQUIRED"}, \
319
  {0xC0000135, "DLL NOT FOUND"}, \
320
  {0xC0000136, "OPEN FAILED"}, \
321
  {0xC0000137, "IO PRIVILEGE FAILED"}, \
322
  {0xC0000138, "ORDINAL NOT FOUND"}, \
323
  {0xC0000139, "ENTRYPOINT NOT FOUND"}, \
324
  {0xC000013A, "CONTROL C EXIT"}, \
325
  {0xC000013B, "LOCAL DISCONNECT"}, \
326
  {0xC000013C, "REMOTE DISCONNECT"}, \
327
  {0xC000013D, "REMOTE RESOURCES"}, \
328
  {0xC000013E, "LINK FAILED"}, \
329
  {0xC000013F, "LINK TIMEOUT"}, \
330
  {0xC0000140, "INVALID CONNECTION"}, \
331
  {0xC0000141, "INVALID ADDRESS"}, \
332
  {0xC0000142, "DLL INIT FAILED"}, \
333
  {0xC0000143, "MISSING SYSTEMFILE"}, \
334
  {0xC0000144, "UNHANDLED EXCEPTION"}, \
335
  {0xC0000145, "APP INIT FAILURE"}, \
336
  {0xC0000146, "PAGEFILE CREATE FAILED"}, \
337
  {0xC0000147, "NO PAGEFILE"}, \
338
  {0xC0000148, "INVALID LEVEL"}, \
339
  {0xC0000149, "WRONG PASSWORD CORE"}, \
340
  {0xC000014A, "ILLEGAL FLOAT CONTEXT"}, \
341
  {0xC000014B, "PIPE BROKEN"}, \
342
  {0xC000014C, "REGISTRY CORRUPT"}, \
343
  {0xC000014D, "REGISTRY IO FAILED"}, \
344
  {0xC000014E, "NO EVENT PAIR"}, \
345
  {0xC000014F, "UNRECOGNIZED VOLUME"}, \
346
  {0xC0000150, "SERIAL NO DEVICE INITED"}, \
347
  {0xC0000151, "NO SUCH ALIAS"}, \
348
  {0xC0000152, "MEMBER NOT IN ALIAS"}, \
349
  {0xC0000153, "MEMBER IN ALIAS"}, \
350
  {0xC0000154, "ALIAS EXISTS"}, \
351
  {0xC0000155, "LOGON NOT GRANTED"}, \
352
  {0xC0000156, "TOO MANY SECRETS"}, \
353
  {0xC0000157, "SECRET TOO LONG"}, \
354
  {0xC0000158, "INTERNAL DB ERROR"}, \
355
  {0xC0000159, "FULLSCREEN MODE"}, \
356
  {0xC000015A, "TOO MANY CONTEXT IDS"}, \
357
  {0xC000015B, "LOGON TYPE NOT GRANTED"}, \
358
  {0xC000015C, "NOT REGISTRY FILE"}, \
359
  {0xC000015D, "NT CROSS ENCRYPTION REQUIRED"}, \
360
  {0xC000015E, "DOMAIN CTRLR CONFIG ERROR"}, \
361
  {0xC000015F, "FT MISSING MEMBER"}, \
362
  {0xC0000160, "ILL FORMED SERVICE ENTRY"}, \
363
  {0xC0000161, "ILLEGAL CHARACTER"}, \
364
  {0xC0000162, "UNMAPPABLE CHARACTER"}, \
365
  {0xC0000163, "UNDEFINED CHARACTER"}, \
366
  {0xC0000164, "FLOPPY VOLUME"}, \
367
  {0xC0000165, "FLOPPY ID MARK NOT FOUND"}, \
368
  {0xC0000166, "FLOPPY WRONG CYLINDER"}, \
369
  {0xC0000167, "FLOPPY UNKNOWN ERROR"}, \
370
  {0xC0000168, "FLOPPY BAD REGISTERS"}, \
371
  {0xC0000169, "DISK RECALIBRATE FAILED"}, \
372
  {0xC000016A, "DISK OPERATION FAILED"}, \
373
  {0xC000016B, "DISK RESET FAILED"}, \
374
  {0xC000016C, "SHARED IRQ BUSY"}, \
375
  {0xC000016D, "FT ORPHANING"}, \
376
  {0xC000016E, "BIOS FAILED TO CONNECT INTERRUPT"}, \
377
  {0xC0000172, "PARTITION FAILURE"}, \
378
  {0xC0000173, "INVALID BLOCK LENGTH"}, \
379
  {0xC0000174, "DEVICE NOT PARTITIONED"}, \
380
  {0xC0000175, "UNABLE TO LOCK MEDIA"}, \
381
  {0xC0000176, "UNABLE TO UNLOAD MEDIA"}, \
382
  {0xC0000177, "EOM OVERFLOW"}, \
383
  {0xC0000178, "NO MEDIA"}, \
384
  {0xC000017A, "NO SUCH MEMBER"}, \
385
  {0xC000017B, "INVALID MEMBER"}, \
386
  {0xC000017C, "KEY DELETED"}, \
387
  {0xC000017D, "NO LOG SPACE"}, \
388
  {0xC000017E, "TOO MANY SIDS"}, \
389
  {0xC000017F, "LM CROSS ENCRYPTION REQUIRED"}, \
390
  {0xC0000180, "KEY HAS CHILDREN"}, \
391
  {0xC0000181, "CHILD MUST BE VOLATILE"}, \
392
  {0xC0000182, "DEVICE CONFIGURATION ERROR"}, \
393
  {0xC0000183, "DRIVER INTERNAL ERROR"}, \
394
  {0xC0000184, "INVALID DEVICE STATE"}, \
395
  {0xC0000185, "IO DEVICE ERROR"}, \
396
  {0xC0000186, "DEVICE PROTOCOL ERROR"}, \
397
  {0xC0000187, "BACKUP CONTROLLER"}, \
398
  {0xC0000188, "LOG FILE FULL"}, \
399
  {0xC0000189, "TOO LATE"}, \
400
  {0xC000018A, "NO TRUST LSA SECRET"}, \
401
  {0xC000018B, "NO TRUST SAM ACCOUNT"}, \
402
  {0xC000018C, "TRUSTED DOMAIN FAILURE"}, \
403
  {0xC000018D, "TRUSTED RELATIONSHIP FAILURE"}, \
404
  {0xC000018E, "EVENTLOG FILE CORRUPT"}, \
405
  {0xC000018F, "EVENTLOG CANT START"}, \
406
  {0xC0000190, "TRUST FAILURE"}, \
407
  {0xC0000191, "MUTANT LIMIT EXCEEDED"}, \
408
  {0xC0000192, "NETLOGON NOT STARTED"}, \
409
  {0xC0000193, "ACCOUNT EXPIRED"}, \
410
  {0xC0000194, "POSSIBLE DEADLOCK"}, \
411
  {0xC0000195, "NETWORK CREDENTIAL CONFLICT"}, \
412
  {0xC0000196, "REMOTE SESSION LIMIT"}, \
413
  {0xC0000197, "EVENTLOG FILE CHANGED"}, \
414
  {0xC0000198, "NOLOGON INTERDOMAIN TRUST ACCOUNT"}, \
415
  {0xC0000199, "NOLOGON WORKSTATION TRUST ACCOUNT"}, \
416
  {0xC000019A, "NOLOGON SERVER TRUST ACCOUNT"}, \
417
  {0xC000019B, "DOMAIN TRUST INCONSISTENT"}, \
418
  {0xC000019C, "FS DRIVER REQUIRED"}, \
419
  {0xC0000202, "NO USER SESSION KEY"}, \
420
  {0xC0000203, "USER SESSION DELETED"}, \
421
  {0xC0000204, "RESOURCE LANG NOT FOUND"}, \
422
  {0xC0000205, "INSUFF SERVER RESOURCES"}, \
423
  {0xC0000206, "INVALID BUFFER SIZE"}, \
424
  {0xC0000207, "INVALID ADDRESS COMPONENT"}, \
425
  {0xC0000208, "INVALID ADDRESS WILDCARD"}, \
426
  {0xC0000209, "TOO MANY ADDRESSES"}, \
427
  {0xC000020A, "ADDRESS ALREADY EXISTS"}, \
428
  {0xC000020B, "ADDRESS CLOSED"}, \
429
  {0xC000020C, "CONNECTION DISCONNECTED"}, \
430
  {0xC000020D, "CONNECTION RESET"}, \
431
  {0xC000020E, "TOO MANY NODES"}, \
432
  {0xC000020F, "TRANSACTION ABORTED"}, \
433
  {0xC0000210, "TRANSACTION TIMED OUT"}, \
434
  {0xC0000211, "TRANSACTION NO RELEASE"}, \
435
  {0xC0000212, "TRANSACTION NO MATCH"}, \
436
  {0xC0000213, "TRANSACTION RESPONDED"}, \
437
  {0xC0000214, "TRANSACTION INVALID ID"}, \
438
  {0xC0000215, "TRANSACTION INVALID TYPE"}, \
439
  {0xC0000216, "NOT SERVER SESSION"}, \
440
  {0xC0000217, "NOT CLIENT SESSION"}, \
441
  {0xC0000218, "CANNOT LOAD REGISTRY FILE"}, \
442
  {0xC0000219, "DEBUG ATTACH FAILED"}, \
443
  {0xC000021A, "SYSTEM PROCESS TERMINATED"}, \
444
  {0xC000021B, "DATA NOT ACCEPTED"}, \
445
  {0xC000021C, "NO BROWSER SERVERS FOUND"}, \
446
  {0xC000021D, "VDM HARD ERROR"}, \
447
  {0xC000021E, "DRIVER CANCEL TIMEOUT"}, \
448
  {0xC000021F, "REPLY MESSAGE MISMATCH"}, \
449
  {0xC0000220, "MAPPED ALIGNMENT"}, \
450
  {0xC0000221, "IMAGE CHECKSUM MISMATCH"}, \
451
  {0xC0000222, "LOST WRITEBEHIND DATA"}, \
452
  {0xC0000223, "CLIENT SERVER PARAMETERS INVALID"}, \
453
  {0xC0000224, "PASSWORD MUST CHANGE"}, \
454
  {0xC0000225, "NOT FOUND"}, \
455
  {0xC0000226, "NOT TINY STREAM"}, \
456
  {0xC0000227, "RECOVERY FAILURE"}, \
457
  {0xC0000228, "STACK OVERFLOW READ"}, \
458
  {0xC0000229, "FAIL CHECK"}, \
459
  {0xC000022A, "DUPLICATE OBJECTID"}, \
460
  {0xC000022B, "OBJECTID EXISTS"}, \
461
  {0xC000022C, "CONVERT TO LARGE"}, \
462
  {0xC000022D, "RETRY"}, \
463
  {0xC000022E, "FOUND OUT OF SCOPE"}, \
464
  {0xC000022F, "ALLOCATE BUCKET"}, \
465
  {0xC0000230, "PROPSET NOT FOUND"}, \
466
  {0xC0000231, "MARSHALL OVERFLOW"}, \
467
  {0xC0000232, "INVALID VARIANT"}, \
468
  {0xC0000233, "DOMAIN CONTROLLER NOT FOUND"}, \
469
  {0xC0000234, "ACCOUNT LOCKED OUT"}, \
470
  {0xC0000235, "HANDLE NOT CLOSABLE"}, \
471
  {0xC0000236, "CONNECTION REFUSED"}, \
472
  {0xC0000237, "GRACEFUL DISCONNECT"}, \
473
  {0xC0000238, "ADDRESS ALREADY ASSOCIATED"}, \
474
  {0xC0000239, "ADDRESS NOT ASSOCIATED"}, \
475
  {0xC000023A, "CONNECTION INVALID"}, \
476
  {0xC000023B, "CONNECTION ACTIVE"}, \
477
  {0xC000023C, "NETWORK UNREACHABLE"}, \
478
  {0xC000023D, "HOST UNREACHABLE"}, \
479
  {0xC000023E, "PROTOCOL UNREACHABLE"}, \
480
  {0xC000023F, "PORT UNREACHABLE"}, \
481
  {0xC0000240, "REQUEST ABORTED"}, \
482
  {0xC0000241, "CONNECTION ABORTED"}, \
483
  {0xC0000242, "BAD COMPRESSION BUFFER"}, \
484
  {0xC0000243, "USER MAPPED FILE"}, \
485
  {0xC0000244, "AUDIT FAILED"}, \
486
  {0xC0000245, "TIMER RESOLUTION NOT SET"}, \
487
  {0xC0000246, "CONNECTION COUNT LIMIT"}, \
488
  {0xC0000247, "LOGIN TIME RESTRICTION"}, \
489
  {0xC0000248, "LOGIN WKSTA RESTRICTION"}, \
490
  {0xC0000249, "IMAGE MP UP MISMATCH"}, \
491
  {0xC0000250, "INSUFFICIENT LOGON INFO"}, \
492
  {0xC0000251, "BAD DLL ENTRYPOINT"}, \
493
  {0xC0000252, "BAD SERVICE ENTRYPOINT"}, \
494
  {0xC0000253, "LPC REPLY LOST"}, \
495
  {0xC0000254, "IP ADDRESS CONFLICT1"}, \
496
  {0xC0000255, "IP ADDRESS CONFLICT2"}, \
497
  {0xC0000256, "REGISTRY QUOTA LIMIT"}, \
498
  {0xC0000257, "PATH NOT COVERED"}, \
499
  {0xC0000258, "NO CALLBACK ACTIVE"}, \
500
  {0xC0000259, "LICENSE QUOTA EXCEEDED"}, \
501
  {0xC000025A, "PWD TOO SHORT"}, \
502
  {0xC000025B, "PWD TOO RECENT"}, \
503
  {0xC000025C, "PWD HISTORY CONFLICT"}, \
504
  {0xC000025E, "PLUGPLAY NO DEVICE"}, \
505
  {0xC000025F, "UNSUPPORTED COMPRESSION"}, \
506
  {0xC0000260, "INVALID HW PROFILE"}, \
507
  {0xC0000261, "INVALID PLUGPLAY DEVICE PATH"}, \
508
  {0xC0000262, "DRIVER ORDINAL NOT FOUND"}, \
509
  {0xC0000263, "DRIVER ENTRYPOINT NOT FOUND"}, \
510
  {0xC0000264, "RESOURCE NOT OWNED"}, \
511
  {0xC0000265, "TOO MANY LINKS"}, \
512
  {0xC0000266, "QUOTA LIST INCONSISTENT"}, \
513
  {0xC0000267, "FILE IS OFFLINE"}, \
514
  {0xC0000268, "EVALUATION EXPIRATION"}, \
515
  {0xC0000269, "ILLEGAL DLL RELOCATION"}, \
516
  {0xC000026A, "LICENSE VIOLATION"}, \
517
  {0xC000026B, "DLL INIT FAILED LOGOFF"}, \
518
  {0xC000026C, "DRIVER UNABLE TO LOAD"}, \
519
  {0xC000026D, "DFS UNAVAILABLE"}, \
520
  {0xC000026E, "VOLUME DISMOUNTED"}, \
521
  {0xC000026F, "WX86 INTERNAL ERROR"}, \
522
  {0xC0000270, "WX86 FLOAT STACK CHECK"}, \
523
  {0xC0000271, "VALIDATE CONTINUE"}, \
524
  {0xC0000272, "NO MATCH"}, \
525
  {0xC0000273, "NO MORE MATCHES"}, \
526
  {0xC0000275, "NOT A REPARSE POINT"}, \
527
  {0xC0000276, "IO REPARSE TAG INVALID"}, \
528
  {0xC0000277, "IO REPARSE TAG MISMATCH"}, \
529
  {0xC0000278, "IO REPARSE DATA INVALID"}, \
530
  {0xC0000279, "IO REPARSE TAG NOT HANDLED"}, \
531
  {0xC0000280, "REPARSE POINT NOT RESOLVED"}, \
532
  {0xC0000281, "DIRECTORY IS A REPARSE POINT"}, \
533
  {0xC0000282, "RANGE LIST CONFLICT"}, \
534
  {0xC0000283, "SOURCE ELEMENT EMPTY"}, \
535
  {0xC0000284, "DESTINATION ELEMENT FULL"}, \
536
  {0xC0000285, "ILLEGAL ELEMENT ADDRESS"}, \
537
  {0xC0000286, "MAGAZINE NOT PRESENT"}, \
538
  {0xC0000287, "REINITIALIZATION NEEDED"}, \
539
  {0xC000028A, "ENCRYPTION FAILED"}, \
540
  {0xC000028B, "DECRYPTION FAILED"}, \
541
  {0xC000028C, "RANGE NOT FOUND"}, \
542
  {0xC000028D, "NO RECOVERY POLICY"}, \
543
  {0xC000028E, "NO EFS"}, \
544
  {0xC000028F, "WRONG EFS"}, \
545
  {0xC0000290, "NO USER KEYS"}, \
546
  {0xC0000291, "FILE NOT ENCRYPTED"}, \
547
  {0xC0000292, "NOT EXPORT FORMAT"}, \
548
  {0xC0000293, "FILE ENCRYPTED"}, \
549
  {0xC0000295, "WMI GUID NOT FOUND"}, \
550
  {0xC0000296, "WMI INSTANCE NOT FOUND"}, \
551
  {0xC0000297, "WMI ITEMID NOT FOUND"}, \
552
  {0xC0000298, "WMI TRY AGAIN"}, \
553
  {0xC0000299, "SHARED POLICY"}, \
554
  {0xC000029A, "POLICY OBJECT NOT FOUND"}, \
555
  {0xC000029B, "POLICY ONLY IN DS"}, \
556
  {0xC000029C, "VOLUME NOT UPGRADED"}, \
557
  {0xC000029D, "REMOTE STORAGE NOT ACTIVE"}, \
558
  {0xC000029E, "REMOTE STORAGE MEDIA ERROR"}, \
559
  {0xC000029F, "NO TRACKING SERVICE"}, \
560
  {0xC00002A0, "SERVER SID MISMATCH"}, \
561
  {0xC00002A1, "DS NO ATTRIBUTE OR VALUE"}, \
562
  {0xC00002A2, "DS INVALID ATTRIBUTE SYNTAX"}, \
563
  {0xC00002A3, "DS ATTRIBUTE TYPE UNDEFINED"}, \
564
  {0xC00002A4, "DS ATTRIBUTE OR VALUE EXISTS"}, \
565
  {0xC00002A5, "DS BUSY"}, \
566
  {0xC00002A6, "DS UNAVAILABLE"}, \
567
  {0xC00002A7, "DS NO RIDS ALLOCATED"}, \
568
  {0xC00002A8, "DS NO MORE RIDS"}, \
569
  {0xC00002A9, "DS INCORRECT ROLE OWNER"}, \
570
  {0xC00002AA, "DS RIDMGR INIT ERROR"}, \
571
  {0xC00002AB, "DS OBJ CLASS VIOLATION"}, \
572
  {0xC00002AC, "DS CANT ON NON LEAF"}, \
573
  {0xC00002AD, "DS CANT ON RDN"}, \
574
  {0xC00002AE, "DS CANT MOD OBJ CLASS"}, \
575
  {0xC00002AF, "DS CROSS DOM MOVE FAILED"}, \
576
  {0xC00002B0, "DS GC NOT AVAILABLE"}, \
577
  {0xC00002B1, "DIRECTORY SERVICE REQUIRED"}, \
578
  {0xC00002B2, "REPARSE ATTRIBUTE CONFLICT"}, \
579
  {0xC00002B3, "CANT ENABLE DENY ONLY"}, \
580
  {0xC00002B4, "FLOAT MULTIPLE FAULTS"}, \
581
  {0xC00002B5, "FLOAT MULTIPLE TRAPS"}, \
582
  {0xC00002B6, "DEVICE REMOVED"}, \
583
  {0xC00002B7, "JOURNAL DELETE IN PROGRESS"}, \
584
  {0xC00002B8, "JOURNAL NOT ACTIVE"}, \
585
  {0xC00002B9, "NOINTERFACE"}, \
586
  {0xC00002C1, "DS ADMIN LIMIT EXCEEDED"}, \
587
  {0xC00002C2, "DRIVER FAILED SLEEP"}, \
588
  {0xC00002C3, "MUTUAL AUTHENTICATION FAILED"}, \
589
  {0xC00002C4, "CORRUPT SYSTEM FILE"}, \
590
  {0xC00002C5, "DATATYPE MISALIGNMENT ERROR"}, \
591
  {0xC00002C6, "WMI READ ONLY"}, \
592
  {0xC00002C7, "WMI SET FAILURE"}, \
593
  {0xC00002C8, "COMMITMENT MINIMUM"}, \
594
  {0xC00002C9, "REG NAT CONSUMPTION"}, \
595
  {0xC00002CA, "TRANSPORT FULL"}, \
596
  {0xC00002CB, "DS SAM INIT FAILURE"}, \
597
  {0xC00002CC, "ONLY IF CONNECTED"}, \
598
  {0xC00002CD, "DS SENSITIVE GROUP VIOLATION"}, \
599
  {0xC00002CE, "PNP RESTART ENUMERATION"}, \
600
  {0xC00002CF, "JOURNAL ENTRY DELETED"}, \
601
  {0xC00002D0, "DS CANT MOD PRIMARYGROUPID"}, \
602
  {0xC00002D1, "SYSTEM IMAGE BAD SIGNATURE"}, \
603
  {0xC00002D2, "PNP REBOOT REQUIRED"}, \
604
  {0xC00002D3, "POWER STATE INVALID"}, \
605
  {0xC00002D4, "DS INVALID GROUP TYPE"}, \
606
  {0xC00002D5, "DS NO NEST GLOBALGROUP IN MIXEDDOMAIN"}, \
607
  {0xC00002D6, "DS NO NEST LOCALGROUP IN MIXEDDOMAIN"}, \
608
  {0xC00002D7, "DS GLOBAL CANT HAVE LOCAL MEMBER"}, \
609
  {0xC00002D8, "DS GLOBAL CANT HAVE UNIVERSAL MEMBER"}, \
610
  {0xC00002D9, "DS UNIVERSAL CANT HAVE LOCAL MEMBER"}, \
611
  {0xC00002DA, "DS GLOBAL CANT HAVE CROSSDOMAIN MEMBER"}, \
612
  {0xC00002DB, "DS LOCAL CANT HAVE CROSSDOMAIN LOCAL MEMBER"}, \
613
  {0xC00002DC, "DS HAVE PRIMARY MEMBERS"}, \
614
  {0xC00002DD, "WMI NOT SUPPORTED"}, \
615
  {0xC00002DE, "INSUFFICIENT POWER"}, \
616
  {0xC00002DF, "SAM NEED BOOTKEY PASSWORD"}, \
617
  {0xC00002E0, "SAM NEED BOOTKEY FLOPPY"}, \
618
  {0xC00002E1, "DS CANT START"}, \
619
  {0xC00002E2, "DS INIT FAILURE"}, \
620
  {0xC00002E3, "SAM INIT FAILURE"}, \
621
  {0xC00002E4, "DS GC REQUIRED"}, \
622
  {0xC00002E5, "DS LOCAL MEMBER OF LOCAL ONLY"}, \
623
  {0xC00002E6, "DS NO FPO IN UNIVERSAL GROUPS"}, \
624
  {0xC00002E7, "DS MACHINE ACCOUNT QUOTA EXCEEDED"}, \
625
  {0xC00002E8, "MULTIPLE FAULT VIOLATION"}, \
626
  {0xC00002E9, "CURRENT DOMAIN NOT ALLOWED"}, \
627
  {0xC00002EA, "CANNOT MAKE"}, \
628
  {0xC00002EB, "SYSTEM SHUTDOWN"}, \
629
  {0xC00002EC, "DS INIT FAILURE CONSOLE"}, \
630
  {0xC00002ED, "DS SAM INIT FAILURE CONSOLE"}, \
631
  {0xC00002EE, "UNFINISHED CONTEXT DELETED"}, \
632
  {0xC00002EF, "NO TGT REPLY"}, \
633
  {0xC00002F0, "OBJECTID NOT FOUND"}, \
634
  {0xC00002F1, "NO IP ADDRESSES"}, \
635
  {0xC00002F2, "WRONG CREDENTIAL HANDLE"}, \
636
  {0xC00002F3, "CRYPTO SYSTEM INVALID"}, \
637
  {0xC00002F4, "MAX REFERRALS EXCEEDED"}, \
638
  {0xC00002F5, "MUST BE KDC"}, \
639
  {0xC00002F6, "STRONG CRYPTO NOT SUPPORTED"}, \
640
  {0xC00002F7, "TOO MANY PRINCIPALS"}, \
641
  {0xC00002F8, "NO PA DATA"}, \
642
  {0xC00002F9, "PKINIT NAME MISMATCH"}, \
643
  {0xC00002FA, "SMARTCARD LOGON REQUIRED"}, \
644
  {0xC00002FB, "KDC INVALID REQUEST"}, \
645
  {0xC00002FC, "KDC UNABLE TO REFER"}, \
646
  {0xC00002FD, "KDC UNKNOWN ETYPE"}, \
647
  {0xC00002FE, "SHUTDOWN IN PROGRESS"}, \
648
  {0xC00002FF, "SERVER SHUTDOWN IN PROGRESS"}, \
649
  {0xC0000300, "NOT SUPPORTED ON SBS"}, \
650
  {0xC0000301, "WMI GUID DISCONNECTED"}, \
651
  {0xC0000302, "WMI ALREADY DISABLED"}, \
652
  {0xC0000303, "WMI ALREADY ENABLED"}, \
653
  {0xC0000304, "MFT TOO FRAGMENTED"}, \
654
  {0xC0000305, "COPY PROTECTION FAILURE"}, \
655
  {0xC0000306, "CSS AUTHENTICATION FAILURE"}, \
656
  {0xC0000307, "CSS KEY NOT PRESENT"}, \
657
  {0xC0000308, "CSS KEY NOT ESTABLISHED"}, \
658
  {0xC0000309, "CSS SCRAMBLED SECTOR"}, \
659
  {0xC000030A, "CSS REGION MISMATCH"}, \
660
  {0xC000030B, "CSS RESETS EXHAUSTED"}, \
661
  {0xC0000320, "PKINIT FAILURE"}, \
662
  {0xC0000321, "SMARTCARD SUBSYSTEM FAILURE"}, \
663
  {0xC0000322, "NO KERB KEY"}, \
664
  {0xC0000350, "HOST DOWN"}, \
665
  {0xC0000351, "UNSUPPORTED PREAUTH"}, \
666
  {0xC0000352, "EFS ALG BLOB TOO BIG"}, \
667
  {0xC0000353, "PORT NOT SET"}, \
668
  {0xC0000354, "DEBUGGER INACTIVE"}, \
669
  {0xC0000355, "DS VERSION CHECK FAILURE"}, \
670
  {0xC0000356, "AUDITING DISABLED"}, \
671
  {0xC0000357, "PRENT4 MACHINE ACCOUNT"}, \
672
  {0xC0000358, "DS AG CANT HAVE UNIVERSAL MEMBER"}, \
673
  {0xC0000359, "INVALID IMAGE WIN 32"}, \
674
  {0xC000035A, "INVALID IMAGE WIN 64"}, \
675
  {0xC000035B, "BAD BINDINGS"}, \
676
  {0xC000035C, "NETWORK SESSION EXPIRED"}, \
677
  {0xC000035D, "APPHELP BLOCK"}, \
678
  {0xC000035E, "ALL SIDS FILTERED"}, \
679
  {0xC000035F, "NOT SAFE MODE DRIVER"}, \
680
  {0xC0000361, "ACCESS DISABLED BY POLICY DEFAULT"}, \
681
  {0xC0000362, "ACCESS DISABLED BY POLICY PATH"}, \
682
  {0xC0000363, "ACCESS DISABLED BY POLICY PUBLISHER"}, \
683
  {0xC0000364, "ACCESS DISABLED BY POLICY OTHER"}, \
684
  {0xC0000365, "FAILED DRIVER ENTRY"}, \
685
  {0xC0000366, "DEVICE ENUMERATION ERROR"}, \
686
  {0xC0000367, "WAIT FOR OPLOCK"}, \
687
  {0xC0000368, "MOUNT POINT NOT RESOLVED"}, \
688
  {0xC0000369, "INVALID DEVICE OBJECT PARAMETER"}, \
689
  {0xC000036A, "MCA OCCURED"}, \
690
  {0xC000036B, "DRIVER BLOCKED CRITICAL"}, \
691
  {0xC000036C, "DRIVER BLOCKED"}, \
692
  {0xC000036D, "DRIVER DATABASE ERROR"}, \
693
  {0xC000036E, "SYSTEM HIVE TOO LARGE"}, \
694
  {0xC000036F, "INVALID IMPORT OF NON DLL"}, \
695
  {0xC0000380, "SMARTCARD WRONG PIN"}, \
696
  {0xC0000381, "SMARTCARD CARD BLOCKED"}, \
697
  {0xC0000382, "SMARTCARD CARD NOT AUTHENTICATED"}, \
698
  {0xC0000383, "SMARTCARD NO CARD"}, \
699
  {0xC0000384, "SMARTCARD NO KEY CONTAINER"}, \
700
  {0xC0000385, "SMARTCARD NO CERTIFICATE"}, \
701
  {0xC0000386, "SMARTCARD NO KEYSET"}, \
702
  {0xC0000387, "SMARTCARD IO ERROR"}, \
703
  {0xC0000388, "DOWNGRADE DETECTED"}, \
704
  {0xC0000389, "SMARTCARD CERT REVOKED"}, \
705
  {0xC000038A, "ISSUING CA UNTRUSTED"}, \
706
  {0xC000038B, "REVOCATION OFFLINE C"}, \
707
  {0xC000038C, "PKINIT CLIENT FAILURE"}, \
708
  {0xC000038D, "SMARTCARD CERT EXPIRED"}, \
709
  {0xC000038E, "DRIVER FAILED PRIOR UNLOAD"}, \
710
  {0xC000038F, "SMARTCARD SILENT CONTEXT"}, \
711
  {0xC0000401, "PER USER TRUST QUOTA EXCEEDED"}, \
712
  {0xC0000402, "ALL USER TRUST QUOTA EXCEEDED"}, \
713
  {0xC0000403, "USER DELETE TRUST QUOTA EXCEEDED"}, \
714
  {0xC0000404, "DS NAME NOT UNIQUE"}, \
715
  {0xC0000405, "DS DUPLICATE ID FOUND"}, \
716
  {0xC0000406, "DS GROUP CONVERSION ERROR"}, \
717
  {0xC0000407, "VOLSNAP PREPARE HIBERNATE"}, \
718
  {0xC0000408, "USER2USER REQUIRED"}, \
719
  {0xC0000409, "STACK BUFFER OVERRUN"}, \
720
  {0xC000040A, "NO S4U PROT SUPPORT"}, \
721
  {0xC000040B, "CROSSREALM DELEGATION FAILURE"}, \
722
  {0xC000040C, "REVOCATION OFFLINE KDC"}, \
723
  {0xC000040D, "ISSUING CA UNTRUSTED KDC"}, \
724
  {0xC000040E, "KDC CERT EXPIRED"}, \
725
  {0xC000040F, "KDC CERT REVOKED"}, \
726
  {0xC0000410, "PARAMETER QUOTA EXCEEDED"}, \
727
  {0xC0000411, "HIBERNATION FAILURE"}, \
728
  {0xC0000412, "DELAY LOAD FAILED"}, \
729
  {0xC0000413, "AUTHENTICATION FIREWALL FAILED"}, \
730
  {0xC0000414, "VDM DISALLOWED"}, \
731
  {0xC0000415, "HUNG DISPLAY DRIVER THREAD"}, \
732
  {0xC0009898, "WOW ASSERTION"}, \
733
  {0xC0020001, "RPC NT INVALID STRING BINDING"}, \
734
  {0xC0020002, "RPC NT WRONG KIND OF BINDING"}, \
735
  {0xC0020003, "RPC NT INVALID BINDING"}, \
736
  {0xC0020004, "RPC NT PROTSEQ NOT SUPPORTED"}, \
737
  {0xC0020005, "RPC NT INVALID RPC PROTSEQ"}, \
738
  {0xC0020006, "RPC NT INVALID STRING UUID"}, \
739
  {0xC0020007, "RPC NT INVALID ENDPOINT FORMAT"}, \
740
  {0xC0020008, "RPC NT INVALID NET ADDR"}, \
741
  {0xC0020009, "RPC NT NO ENDPOINT FOUND"}, \
742
  {0xC002000A, "RPC NT INVALID TIMEOUT"}, \
743
  {0xC002000B, "RPC NT OBJECT NOT FOUND"}, \
744
  {0xC002000C, "RPC NT ALREADY REGISTERED"}, \
745
  {0xC002000D, "RPC NT TYPE ALREADY REGISTERED"}, \
746
  {0xC002000E, "RPC NT ALREADY LISTENING"}, \
747
  {0xC002000F, "RPC NT NO PROTSEQS REGISTERED"}, \
748
  {0xC0020010, "RPC NT NOT LISTENING"}, \
749
  {0xC0020011, "RPC NT UNKNOWN MGR TYPE"}, \
750
  {0xC0020012, "RPC NT UNKNOWN IF"}, \
751
  {0xC0020013, "RPC NT NO BINDINGS"}, \
752
  {0xC0020014, "RPC NT NO PROTSEQS"}, \
753
  {0xC0020015, "RPC NT CANT CREATE ENDPOINT"}, \
754
  {0xC0020016, "RPC NT OUT OF RESOURCES"}, \
755
  {0xC0020017, "RPC NT SERVER UNAVAILABLE"}, \
756
  {0xC0020018, "RPC NT SERVER TOO BUSY"}, \
757
  {0xC0020019, "RPC NT INVALID NETWORK OPTIONS"}, \
758
  {0xC002001A, "RPC NT NO CALL ACTIVE"}, \
759
  {0xC002001B, "RPC NT CALL FAILED"}, \
760
  {0xC002001C, "RPC NT CALL FAILED DNE"}, \
761
  {0xC002001D, "RPC NT PROTOCOL ERROR"}, \
762
  {0xC002001F, "RPC NT UNSUPPORTED TRANS SYN"}, \
763
  {0xC0020021, "RPC NT UNSUPPORTED TYPE"}, \
764
  {0xC0020022, "RPC NT INVALID TAG"}, \
765
  {0xC0020023, "RPC NT INVALID BOUND"}, \
766
  {0xC0020024, "RPC NT NO ENTRY NAME"}, \
767
  {0xC0020025, "RPC NT INVALID NAME SYNTAX"}, \
768
  {0xC0020026, "RPC NT UNSUPPORTED NAME SYNTAX"}, \
769
  {0xC0020028, "RPC NT UUID NO ADDRESS"}, \
770
  {0xC0020029, "RPC NT DUPLICATE ENDPOINT"}, \
771
  {0xC002002A, "RPC NT UNKNOWN AUTHN TYPE"}, \
772
  {0xC002002B, "RPC NT MAX CALLS TOO SMALL"}, \
773
  {0xC002002C, "RPC NT STRING TOO LONG"}, \
774
  {0xC002002D, "RPC NT PROTSEQ NOT FOUND"}, \
775
  {0xC002002E, "RPC NT PROCNUM OUT OF RANGE"}, \
776
  {0xC002002F, "RPC NT BINDING HAS NO AUTH"}, \
777
  {0xC0020030, "RPC NT UNKNOWN AUTHN SERVICE"}, \
778
  {0xC0020031, "RPC NT UNKNOWN AUTHN LEVEL"}, \
779
  {0xC0020032, "RPC NT INVALID AUTH IDENTITY"}, \
780
  {0xC0020033, "RPC NT UNKNOWN AUTHZ SERVICE"}, \
781
  {0xC0020034, "EPT NT INVALID ENTRY"}, \
782
  {0xC0020035, "EPT NT CANT PERFORM OP"}, \
783
  {0xC0020036, "EPT NT NOT REGISTERED"}, \
784
  {0xC0020037, "RPC NT NOTHING TO EXPORT"}, \
785
  {0xC0020038, "RPC NT INCOMPLETE NAME"}, \
786
  {0xC0020039, "RPC NT INVALID VERS OPTION"}, \
787
  {0xC002003A, "RPC NT NO MORE MEMBERS"}, \
788
  {0xC002003B, "RPC NT NOT ALL OBJS UNEXPORTED"}, \
789
  {0xC002003C, "RPC NT INTERFACE NOT FOUND"}, \
790
  {0xC002003D, "RPC NT ENTRY ALREADY EXISTS"}, \
791
  {0xC002003E, "RPC NT ENTRY NOT FOUND"}, \
792
  {0xC002003F, "RPC NT NAME SERVICE UNAVAILABLE"}, \
793
  {0xC0020040, "RPC NT INVALID NAF ID"}, \
794
  {0xC0020041, "RPC NT CANNOT SUPPORT"}, \
795
  {0xC0020042, "RPC NT NO CONTEXT AVAILABLE"}, \
796
  {0xC0020043, "RPC NT INTERNAL ERROR"}, \
797
  {0xC0020044, "RPC NT ZERO DIVIDE"}, \
798
  {0xC0020045, "RPC NT ADDRESS ERROR"}, \
799
  {0xC0020046, "RPC NT FP DIV ZERO"}, \
800
  {0xC0020047, "RPC NT FP UNDERFLOW"}, \
801
  {0xC0020048, "RPC NT FP OVERFLOW"}, \
802
  {0xC0020049, "RPC NT CALL IN PROGRESS"}, \
803
  {0xC002004A, "RPC NT NO MORE BINDINGS"}, \
804
  {0xC002004B, "RPC NT GROUP MEMBER NOT FOUND"}, \
805
  {0xC002004C, "EPT NT CANT CREATE"}, \
806
  {0xC002004D, "RPC NT INVALID OBJECT"}, \
807
  {0xC002004F, "RPC NT NO INTERFACES"}, \
808
  {0xC0020050, "RPC NT CALL CANCELLED"}, \
809
  {0xC0020051, "RPC NT BINDING INCOMPLETE"}, \
810
  {0xC0020052, "RPC NT COMM FAILURE"}, \
811
  {0xC0020053, "RPC NT UNSUPPORTED AUTHN LEVEL"}, \
812
  {0xC0020054, "RPC NT NO PRINC NAME"}, \
813
  {0xC0020055, "RPC NT NOT RPC ERROR"}, \
814
  {0xC0020057, "RPC NT SEC PKG ERROR"}, \
815
  {0xC0020058, "RPC NT NOT CANCELLED"}, \
816
  {0xC0020062, "RPC NT INVALID ASYNC HANDLE"}, \
817
  {0xC0020063, "RPC NT INVALID ASYNC CALL"}, \
818
  {0xC0030001, "RPC NT NO MORE ENTRIES"}, \
819
  {0xC0030002, "RPC NT SS CHAR TRANS OPEN FAIL"}, \
820
  {0xC0030003, "RPC NT SS CHAR TRANS SHORT FILE"}, \
821
  {0xC0030004, "RPC NT SS IN NULL CONTEXT"}, \
822
  {0xC0030005, "RPC NT SS CONTEXT MISMATCH"}, \
823
  {0xC0030006, "RPC NT SS CONTEXT DAMAGED"}, \
824
  {0xC0030007, "RPC NT SS HANDLES MISMATCH"}, \
825
  {0xC0030008, "RPC NT SS CANNOT GET CALL HANDLE"}, \
826
  {0xC0030009, "RPC NT NULL REF POINTER"}, \
827
  {0xC003000A, "RPC NT ENUM VALUE OUT OF RANGE"}, \
828
  {0xC003000B, "RPC NT BYTE COUNT TOO SMALL"}, \
829
  {0xC003000C, "RPC NT BAD STUB DATA"}, \
830
  {0xC0030059, "RPC NT INVALID ES ACTION"}, \
831
  {0xC003005A, "RPC NT WRONG ES VERSION"}, \
832
  {0xC003005B, "RPC NT WRONG STUB VERSION"}, \
833
  {0xC003005C, "RPC NT INVALID PIPE OBJECT"}, \
834
  {0xC003005D, "RPC NT INVALID PIPE OPERATION"}, \
835
  {0xC003005E, "RPC NT WRONG PIPE VERSION"}, \
836
  {0xC003005F, "RPC NT PIPE CLOSED"}, \
837
  {0xC0030060, "RPC NT PIPE DISCIPLINE ERROR"}, \
838
  {0xC0030061, "RPC NT PIPE EMPTY"}, \
839
  {0xC0040035, "PNP BAD MPS TABLE"}, \
840
  {0xC0040036, "PNP TRANSLATION FAILED"}, \
841
  {0xC0040037, "PNP IRQ TRANSLATION FAILED"}, \
842
  {0xC0040038, "PNP INVALID ID"}, \
843
  {0xC00A0001, "CTX WINSTATION NAME INVALID"}, \
844
  {0xC00A0002, "CTX INVALID PD"}, \
845
  {0xC00A0003, "CTX PD NOT FOUND"}, \
846
  {0xC00A0006, "CTX CLOSE PENDING"}, \
847
  {0xC00A0007, "CTX NO OUTBUF"}, \
848
  {0xC00A0008, "CTX MODEM INF NOT FOUND"}, \
849
  {0xC00A0009, "CTX INVALID MODEMNAME"}, \
850
  {0xC00A000A, "CTX RESPONSE ERROR"}, \
851
  {0xC00A000B, "CTX MODEM RESPONSE TIMEOUT"}, \
852
  {0xC00A000C, "CTX MODEM RESPONSE NO CARRIER"}, \
853
  {0xC00A000D, "CTX MODEM RESPONSE NO DIALTONE"}, \
854
  {0xC00A000E, "CTX MODEM RESPONSE BUSY"}, \
855
  {0xC00A000F, "CTX MODEM RESPONSE VOICE"}, \
856
  {0xC00A0010, "CTX TD ERROR"}, \
857
  {0xC00A0012, "CTX LICENSE CLIENT INVALID"}, \
858
  {0xC00A0013, "CTX LICENSE NOT AVAILABLE"}, \
859
  {0xC00A0014, "CTX LICENSE EXPIRED"}, \
860
  {0xC00A0015, "CTX WINSTATION NOT FOUND"}, \
861
  {0xC00A0016, "CTX WINSTATION NAME COLLISION"}, \
862
  {0xC00A0017, "CTX WINSTATION BUSY"}, \
863
  {0xC00A0018, "CTX BAD VIDEO MODE"}, \
864
  {0xC00A0022, "CTX GRAPHICS INVALID"}, \
865
  {0xC00A0024, "CTX NOT CONSOLE"}, \
866
  {0xC00A0026, "CTX CLIENT QUERY TIMEOUT"}, \
867
  {0xC00A0027, "CTX CONSOLE DISCONNECT"}, \
868
  {0xC00A0028, "CTX CONSOLE CONNECT"}, \
869
  {0xC00A002A, "CTX SHADOW DENIED"}, \
870
  {0xC00A002B, "CTX WINSTATION ACCESS DENIED"}, \
871
  {0xC00A002E, "CTX INVALID WD"}, \
872
  {0xC00A002F, "CTX WD NOT FOUND"}, \
873
  {0xC00A0030, "CTX SHADOW INVALID"}, \
874
  {0xC00A0031, "CTX SHADOW DISABLED"}, \
875
  {0xC00A0032, "RDP PROTOCOL ERROR"}, \
876
  {0xC00A0033, "CTX CLIENT LICENSE NOT SET"}, \
877
  {0xC00A0034, "CTX CLIENT LICENSE IN USE"}, \
878
  {0xC00A0035, "CTX SHADOW ENDED BY MODE CHANGE"}, \
879
  {0xC00A0036, "CTX SHADOW NOT RUNNING"}, \
880
  {0xC0130001, "CLUSTER INVALID NODE"}, \
881
  {0xC0130002, "CLUSTER NODE EXISTS"}, \
882
  {0xC0130003, "CLUSTER JOIN IN PROGRESS"}, \
883
  {0xC0130004, "CLUSTER NODE NOT FOUND"}, \
884
  {0xC0130005, "CLUSTER LOCAL NODE NOT FOUND"}, \
885
  {0xC0130006, "CLUSTER NETWORK EXISTS"}, \
886
  {0xC0130007, "CLUSTER NETWORK NOT FOUND"}, \
887
  {0xC0130008, "CLUSTER NETINTERFACE EXISTS"}, \
888
  {0xC0130009, "CLUSTER NETINTERFACE NOT FOUND"}, \
889
  {0xC013000A, "CLUSTER INVALID REQUEST"}, \
890
  {0xC013000B, "CLUSTER INVALID NETWORK PROVIDER"}, \
891
  {0xC013000C, "CLUSTER NODE DOWN"}, \
892
  {0xC013000D, "CLUSTER NODE UNREACHABLE"}, \
893
  {0xC013000E, "CLUSTER NODE NOT MEMBER"}, \
894
  {0xC013000F, "CLUSTER JOIN NOT IN PROGRESS"}, \
895
  {0xC0130010, "CLUSTER INVALID NETWORK"}, \
896
  {0xC0130011, "CLUSTER NO NET ADAPTERS"}, \
897
  {0xC0130012, "CLUSTER NODE UP"}, \
898
  {0xC0130013, "CLUSTER NODE PAUSED"}, \
899
  {0xC0130014, "CLUSTER NODE NOT PAUSED"}, \
900
  {0xC0130015, "CLUSTER NO SECURITY CONTEXT"}, \
901
  {0xC0130016, "CLUSTER NETWORK NOT INTERNAL"}, \
902
  {0xC0130017, "CLUSTER POISONED"}, \
903
  {0xC0150001, "SXS SECTION NOT FOUND"}, \
904
  {0xC0150002, "SXS CANT GEN ACTCTX"}, \
905
  {0xC0150003, "SXS INVALID ACTCTXDATA FORMAT"}, \
906
  {0xC0150004, "SXS ASSEMBLY NOT FOUND"}, \
907
  {0xC0150005, "SXS MANIFEST FORMAT ERROR"}, \
908
  {0xC0150006, "SXS MANIFEST PARSE ERROR"}, \
909
  {0xC0150007, "SXS ACTIVATION CONTEXT DISABLED"}, \
910
  {0xC0150008, "SXS KEY NOT FOUND"}, \
911
  {0xC0150009, "SXS VERSION CONFLICT"}, \
912
  {0xC015000A, "SXS WRONG SECTION TYPE"}, \
913
  {0xC015000B, "SXS THREAD QUERIES DISABLED"}, \
914
  {0xC015000C, "SXS ASSEMBLY MISSING"}, \
915
  {0xC015000E, "SXS PROCESS DEFAULT ALREADY SET"}, \
916
  {0xC015000F, "SXS EARLY DEACTIVATION"}, \
917
  {0xC0150010, "SXS INVALID DEACTIVATION"}, \
918
  {0xC0150011, "SXS MULTIPLE DEACTIVATION"}, \
919
  {0xC0150012, "SXS SYSTEM DEFAULT ACTIVATION CONTEXT EMPTY"}, \
920
  {0xC0150013, "SXS PROCESS TERMINATION REQUESTED"}, \
921
  {0xC0150014, "SXS CORRUPT ACTIVATION STACK"}, \
922
  {0xC0150015, "SXS CORRUPTION"}, \
923
}
924
925
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/ntstatus.h (+1994 lines)
Line 0    Link Here 
1
/*
2
 * Win32 definitions for Windows NT
3
 *
4
 * Copyright 1996 Alexandre Julliard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
21
#ifndef _NTSTATUS_
22
#define _NTSTATUS_
23
24
#ifndef WIN32_NO_STATUS
25
26
/*
27
 * Debug codes
28
 */
29
30
#define DBG_EXCEPTION_HANDLED            0x00010001
31
#define DBG_CONTINUE                     0x00010002
32
#define DBG_REPLY_LATER                  0x40010001
33
#define DBG_UNABLE_TO_PROVIDE_HANDLE     0x40010002
34
#define DBG_TERMINATE_THREAD             0x40010003
35
#define DBG_TERMINATE_PROCESS            0x40010004
36
#define DBG_CONTROL_C                    0x40010005
37
#define DBG_PRINTEXCEPTION_C             0x40010006
38
#define DBG_RIPEXCEPTION                 0x40010007
39
#define DBG_CONTROL_BREAK                0x40010008
40
#define DBG_COMMAND_EXCEPTION            0x40010009
41
#define DBG_EXCEPTION_NOT_HANDLED        0x80010001
42
#define DBG_NO_STATE_CHANGE              0xC0010001
43
#define DBG_APP_NOT_IDLE                 0xC0010002
44
45
/*
46
 * Exception codes
47
 */
48
49
#define STATUS_SUCCESS                   0x0
50
#define STATUS_SEVERITY_SUCCESS          0x0
51
#define STATUS_SEVERITY_INFORMATIONAL    0x1
52
#define STATUS_SEVERITY_WARNING          0x2
53
#define STATUS_SEVERITY_ERROR            0x3
54
55
#define STATUS_WAIT_1                    0x00000001
56
#define STATUS_WAIT_2                    0x00000002
57
#define STATUS_WAIT_3                    0x00000003
58
#define STATUS_WAIT_63                   0x0000003f
59
#define STATUS_ABANDONED                 0x00000080
60
#define STATUS_ABANDONED_WAIT_63         0x000000BF
61
#define STATUS_KERNEL_APC                0x00000100
62
#define STATUS_ALERTED                   0x00000101
63
#define STATUS_TIMEOUT                   0x00000102
64
#define STATUS_PENDING                   0x00000103
65
#define STATUS_REPARSE                   0x00000104
66
#define STATUS_MORE_ENTRIES              0x00000105
67
#define STATUS_NOT_ALL_ASSIGNED          0x00000106
68
#define STATUS_SOME_NOT_MAPPED           0x00000107
69
#define STATUS_OPLOCK_BREAK_IN_PROGRESS  0x00000108
70
#define STATUS_VOLUME_MOUNTED            0x00000109
71
#define STATUS_RXACT_COMMITTED           0x0000010A
72
#define STATUS_NOTIFY_CLEANUP            0x0000010B
73
#define STATUS_NOTIFY_ENUM_DIR           0x0000010C
74
#define STATUS_NO_QUOTAS_FOR_ACCOUNT     0x0000010D
75
#define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED 0x0000010E
76
#define STATUS_PAGE_FAULT_TRANSITION     0x00000110
77
#define STATUS_PAGE_FAULT_DEMAND_ZERO    0x00000111
78
#define STATUS_PAGE_FAULT_COPY_ON_WRITE  0x00000112
79
#define STATUS_PAGE_FAULT_GUARD_PAGE     0x00000113
80
#define STATUS_PAGE_FAULT_PAGING_FILE    0x00000114
81
#define STATUS_CACHE_PAGE_LOCKED         0x00000115
82
#define STATUS_CRASH_DUMP                0x00000116
83
#define STATUS_BUFFER_ALL_ZEROS          0x00000117
84
#define STATUS_REPARSE_OBJECT            0x00000118
85
#define STATUS_RESOURCE_REQUIREMENTS_CHANGED 0x00000119
86
#define STATUS_TRANSLATION_COMPLETE      0x00000120
87
#define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY  0x00000121
88
#define STATUS_NOTHING_TO_TERMINATE      0x00000122
89
#define STATUS_PROCESS_NOT_IN_JOB        0x00000123
90
#define STATUS_PROCESS_IN_JOB            0x00000124
91
#define STATUS_VOLSNAP_HIBERNATE_READY   0x00000125
92
#define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY 0x00000126
93
94
#define STATUS_OBJECT_NAME_EXISTS        0x40000000
95
#define STATUS_THREAD_WAS_SUSPENDED      0x40000001
96
#define STATUS_WORKING_SET_LIMIT_RANGE   0x40000002
97
#define STATUS_IMAGE_NOT_AT_BASE         0x40000003
98
#define STATUS_RXACT_STATE_CREATED       0x40000004
99
#define STATUS_SEGMENT_NOTIFICATION      0x40000005
100
#define STATUS_LOCAL_USER_SESSION_KEY    0x40000006
101
#define STATUS_BAD_CURRENT_DIRECTORY     0x40000007
102
#define STATUS_SERIAL_MORE_WRITES        0x40000008
103
#define STATUS_REGISTRY_RECOVERED        0x40000009
104
#define STATUS_FT_READ_RECOVERY_FROM_BACKUP 0x4000000A
105
#define STATUS_FT_WRITE_RECOVERY         0x4000000B
106
#define STATUS_SERIAL_COUNTER_TIMEOUT    0x4000000C
107
#define STATUS_NULL_LM_PASSWORD          0x4000000D
108
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH 0x4000000E
109
#define STATUS_RECEIVE_PARTIAL           0x4000000F
110
#define STATUS_RECEIVE_EXPEDITED         0x40000010
111
#define STATUS_RECEIVE_PARTIAL_EXPEDITED 0x40000011
112
#define STATUS_EVENT_DONE                0x40000012
113
#define STATUS_EVENT_PENDING             0x40000013
114
#define STATUS_CHECKING_FILE_SYSTEM      0x40000014
115
#define STATUS_FATAL_APP_EXIT            0x40000015
116
#define STATUS_PREDEFINED_HANDLE         0x40000016
117
#define STATUS_WAS_UNLOCKED              0x40000017
118
#define STATUS_SERVICE_NOTIFICATION      0x40000018
119
#define STATUS_WAS_LOCKED                0x40000019
120
#define STATUS_LOG_HARD_ERROR            0x4000001A
121
#define STATUS_ALREADY_WIN32             0x4000001B
122
#define STATUS_WX86_UNSIMULATE           0x4000001C
123
#define STATUS_WX86_CONTINUE             0x4000001D
124
#define STATUS_WX86_SINGLE_STEP          0x4000001E
125
#define STATUS_WX86_BREAKPOINT           0x4000001F
126
#define STATUS_WX86_EXCEPTION_CONTINUE   0x40000020
127
#define STATUS_WX86_EXCEPTION_LASTCHANCE 0x40000021
128
#define STATUS_WX86_EXCEPTION_CHAIN      0x40000022
129
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE 0x40000023
130
#define STATUS_NO_YIELD_PERFORMED        0x40000024
131
#define STATUS_TIMER_RESUME_IGNORED      0x40000025
132
#define STATUS_ARBITRATION_UNHANDLED     0x40000026
133
#define STATUS_CARDBUS_NOT_SUPPORTED     0x40000027
134
#define STATUS_WX86_CREATEWX86TIB        0x40000028
135
#define STATUS_MP_PROCESSOR_MISMATCH     0x40000029
136
#define STATUS_HIBERNATED                0x4000002A
137
#define STATUS_RESUME_HIBERNATION        0x4000002B
138
#define STATUS_FIRMWARE_UPDATED          0x4000002C
139
#define STATUS_WAKE_SYSTEM               0x40000294
140
#define STATUS_DS_SHUTTING_DOWN          0x40000370
141
142
#define RPC_NT_UUID_LOCAL_ONLY           0x40020056
143
#define RPC_NT_SEND_INCOMPLETE           0x400200AF
144
145
#define STATUS_CTX_CDM_CONNECT           0x400A0004
146
#define STATUS_CTX_CDM_DISCONNECT        0x400A0005
147
148
#define STATUS_SXS_RELEASE_ACTIVATION_CONTEXT 0x4015000D
149
150
#define STATUS_GUARD_PAGE_VIOLATION      0x80000001
151
#define STATUS_DATATYPE_MISALIGNMENT     0x80000002
152
#define STATUS_BREAKPOINT                0x80000003
153
#define STATUS_SINGLE_STEP               0x80000004
154
#define STATUS_BUFFER_OVERFLOW           0x80000005
155
#define STATUS_NO_MORE_FILES             0x80000006
156
#define STATUS_WAKE_SYSTEM_DEBUGGER      0x80000007
157
158
#define STATUS_HANDLES_CLOSED            0x8000000A
159
#define STATUS_NO_INHERITANCE            0x8000000B
160
#define STATUS_GUID_SUBSTITUTION_MADE    0x8000000C
161
#define STATUS_PARTIAL_COPY              0x8000000D
162
#define STATUS_DEVICE_PAPER_EMPTY        0x8000000E
163
#define STATUS_DEVICE_POWERED_OFF        0x8000000F
164
#define STATUS_DEVICE_OFF_LINE           0x80000010
165
#define STATUS_DEVICE_BUSY               0x80000011
166
#define STATUS_NO_MORE_EAS               0x80000012
167
#define STATUS_INVALID_EA_NAME           0x80000013
168
#define STATUS_EA_LIST_INCONSISTENT      0x80000014
169
#define STATUS_INVALID_EA_FLAG           0x80000015
170
#define STATUS_VERIFY_REQUIRED           0x80000016
171
#define STATUS_EXTRANEOUS_INFORMATION    0x80000017
172
#define STATUS_RXACT_COMMIT_NECESSARY    0x80000018
173
#define STATUS_NO_MORE_ENTRIES           0x8000001A
174
#define STATUS_FILEMARK_DETECTED         0x8000001B
175
#define STATUS_MEDIA_CHANGED             0x8000001C
176
#define STATUS_BUS_RESET                 0x8000001D
177
#define STATUS_END_OF_MEDIA              0x8000001E
178
#define STATUS_BEGINNING_OF_MEDIA        0x8000001F
179
#define STATUS_MEDIA_CHECK               0x80000020
180
#define STATUS_SETMARK_DETECTED          0x80000021
181
#define STATUS_NO_DATA_DETECTED          0x80000022
182
#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES 0x80000023
183
#define STATUS_SERVER_HAS_OPEN_HANDLES   0x80000024
184
#define STATUS_ALREADY_DISCONNECTED      0x80000025
185
#define STATUS_LONGJUMP                  0x80000026
186
#define STATUS_CLEANER_CARTRIDGE_INSTALLED      0x80000027
187
#define STATUS_PLUGPLAY_QUERY_VETOED     0x80000028
188
#define STATUS_UNWIND_CONSOLIDATE        0x80000029
189
#define STATUS_REGISTRY_HIVE_RECOVERED   0x8000002A
190
#define STATUS_DLL_MIGHT_BE_INSECURE     0x8000002B
191
#define STATUS_DLL_MIGHT_BE_INCOMPATIBLE 0x8000002C
192
193
#define STATUS_DEVICE_REQUIRES_CLEANING  0x80000288
194
#define STATUS_DEVICE_DOOR_OPEN          0x80000289
195
196
#define STATUS_CLUSTER_NODE_ALREADY_UP   0x80130001
197
#define STATUS_CLUSTER_NODE_ALREADY_DOWN 0x80130002
198
#define STATUS_CLUSTER_NETWORK_ALREADY_ONLINE   0x80130003
199
#define STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE  0x80130004
200
#define STATUS_CLUSTER_NODE_ALREADY_MEMBER      0x80130005
201
202
#define STATUS_WAIT_0                    0x00000000
203
#define STATUS_UNSUCCESSFUL              0xC0000001
204
#define STATUS_NOT_IMPLEMENTED           0xC0000002
205
#define STATUS_INVALID_INFO_CLASS        0xC0000003
206
#define STATUS_INFO_LENGTH_MISMATCH      0xC0000004
207
#define STATUS_ACCESS_VIOLATION          0xC0000005
208
#define STATUS_IN_PAGE_ERROR             0xC0000006
209
#define STATUS_PAGEFILE_QUOTA            0xC0000007
210
#define STATUS_INVALID_HANDLE            0xC0000008
211
#define STATUS_BAD_INITIAL_STACK         0xC0000009
212
#define STATUS_BAD_INITIAL_PC            0xC000000A
213
#define STATUS_INVALID_CID               0xC000000B
214
#define STATUS_TIMER_NOT_CANCELED        0xC000000C
215
#define STATUS_INVALID_PARAMETER         0xC000000D
216
#define STATUS_NO_SUCH_DEVICE            0xC000000E
217
#define STATUS_NO_SUCH_FILE              0xC000000F
218
#define STATUS_INVALID_DEVICE_REQUEST    0xC0000010
219
#define STATUS_END_OF_FILE               0xC0000011
220
#define STATUS_WRONG_VOLUME              0xC0000012
221
#define STATUS_NO_MEDIA_IN_DEVICE        0xC0000013
222
#define STATUS_UNRECOGNIZED_MEDIA        0xC0000014
223
#define STATUS_NONEXISTENT_SECTOR        0xC0000015
224
#define STATUS_MORE_PROCESSING_REQUIRED  0xC0000016
225
#define STATUS_NO_MEMORY                 0xC0000017
226
#define STATUS_CONFLICTING_ADDRESSES     0xC0000018
227
#define STATUS_NOT_MAPPED_VIEW           0xC0000019
228
#define STATUS_UNABLE_TO_FREE_VM         0xC000001A
229
#define STATUS_UNABLE_TO_DELETE_SECTION  0xC000001B
230
#define STATUS_INVALID_SYSTEM_SERVICE    0xC000001C
231
#define STATUS_ILLEGAL_INSTRUCTION       0xC000001D
232
#define STATUS_INVALID_LOCK_SEQUENCE     0xC000001E
233
#define STATUS_INVALID_VIEW_SIZE         0xC000001F
234
#define STATUS_INVALID_FILE_FOR_SECTION  0xC0000020
235
#define STATUS_ALREADY_COMMITTED         0xC0000021
236
#define STATUS_ACCESS_DENIED             0xC0000022
237
#define STATUS_BUFFER_TOO_SMALL          0xC0000023
238
#define STATUS_OBJECT_TYPE_MISMATCH      0xC0000024
239
#define STATUS_NONCONTINUABLE_EXCEPTION  0xC0000025
240
#define STATUS_INVALID_DISPOSITION       0xC0000026
241
#define STATUS_UNWIND                    0xC0000027
242
#define STATUS_BAD_STACK                 0xC0000028
243
#define STATUS_INVALID_UNWIND_TARGET     0xC0000029
244
#define STATUS_NOT_LOCKED                0xC000002A
245
#define STATUS_PARITY_ERROR              0xC000002B
246
#define STATUS_UNABLE_TO_DECOMMIT_VM     0xC000002C
247
#define STATUS_NOT_COMMITTED             0xC000002D
248
#define STATUS_INVALID_PORT_ATTRIBUTES   0xC000002E
249
#define STATUS_PORT_MESSAGE_TOO_LONG     0xC000002F
250
#define STATUS_INVALID_PARAMETER_MIX     0xC0000030
251
#define STATUS_INVALID_QUOTA_LOWER       0xC0000031
252
#define STATUS_DISK_CORRUPT_ERROR        0xC0000032
253
#define STATUS_OBJECT_NAME_INVALID       0xC0000033
254
#define STATUS_OBJECT_NAME_NOT_FOUND     0xC0000034
255
#define STATUS_OBJECT_NAME_COLLISION     0xC0000035
256
#define STATUS_PORT_DISCONNECTED         0xC0000037
257
#define STATUS_DEVICE_ALREADY_ATTACHED   0xC0000038
258
#define STATUS_OBJECT_PATH_INVALID       0xC0000039
259
#define STATUS_OBJECT_PATH_NOT_FOUND     0xC000003A
260
#define STATUS_OBJECT_PATH_SYNTAX_BAD    0xC000003B
261
#define STATUS_DATA_OVERRUN              0xC000003C
262
#define STATUS_DATA_LATE_ERROR           0xC000003D
263
#define STATUS_DATA_ERROR                0xC000003E
264
#define STATUS_CRC_ERROR                 0xC000003F
265
#define STATUS_SECTION_TOO_BIG           0xC0000040
266
#define STATUS_PORT_CONNECTION_REFUSED   0xC0000041
267
#define STATUS_INVALID_PORT_HANDLE       0xC0000042
268
#define STATUS_SHARING_VIOLATION         0xC0000043
269
#define STATUS_QUOTA_EXCEEDED            0xC0000044
270
#define STATUS_INVALID_PAGE_PROTECTION   0xC0000045
271
#define STATUS_MUTANT_NOT_OWNED          0xC0000046
272
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED  0xC0000047
273
#define STATUS_PORT_ALREADY_SET          0xC0000048
274
#define STATUS_SECTION_NOT_IMAGE         0xC0000049
275
#define STATUS_SUSPEND_COUNT_EXCEEDED    0xC000004A
276
#define STATUS_THREAD_IS_TERMINATING     0xC000004B
277
#define STATUS_BAD_WORKING_SET_LIMIT     0xC000004C
278
#define STATUS_INCOMPATIBLE_FILE_MAP     0xC000004D
279
#define STATUS_SECTION_PROTECTION        0xC000004E
280
#define STATUS_EAS_NOT_SUPPORTED         0xC000004F
281
#define STATUS_EA_TOO_LARGE              0xC0000050
282
#define STATUS_NONEXISTENT_EA_ENTRY      0xC0000051
283
#define STATUS_NO_EAS_ON_FILE            0xC0000052
284
#define STATUS_EA_CORRUPT_ERROR          0xC0000053
285
#define STATUS_FILE_LOCK_CONFLICT        0xC0000054
286
#define STATUS_LOCK_NOT_GRANTED          0xC0000055
287
#define STATUS_DELETE_PENDING            0xC0000056
288
#define STATUS_CTL_FILE_NOT_SUPPORTED    0xC0000057
289
#define STATUS_UNKNOWN_REVISION          0xC0000058
290
#define STATUS_REVISION_MISMATCH         0xC0000059
291
#define STATUS_INVALID_OWNER             0xC000005A
292
#define STATUS_INVALID_PRIMARY_GROUP     0xC000005B
293
#define STATUS_NO_IMPERSONATION_TOKEN    0xC000005C
294
#define STATUS_CANT_DISABLE_MANDATORY    0xC000005D
295
#define STATUS_NO_LOGON_SERVERS          0xC000005E
296
#define STATUS_NO_SUCH_LOGON_SESSION     0xC000005F
297
#define STATUS_NO_SUCH_PRIVILEGE         0xC0000060
298
#define STATUS_PRIVILEGE_NOT_HELD        0xC0000061
299
#define STATUS_INVALID_ACCOUNT_NAME      0xC0000062
300
#define STATUS_USER_EXISTS               0xC0000063
301
#define STATUS_NO_SUCH_USER              0xC0000064
302
#define STATUS_GROUP_EXISTS              0xC0000065
303
#define STATUS_NO_SUCH_GROUP             0xC0000066
304
#define STATUS_MEMBER_IN_GROUP           0xC0000067
305
#define STATUS_MEMBER_NOT_IN_GROUP       0xC0000068
306
#define STATUS_LAST_ADMIN                0xC0000069
307
#define STATUS_WRONG_PASSWORD            0xC000006A
308
#define STATUS_ILL_FORMED_PASSWORD       0xC000006B
309
#define STATUS_PASSWORD_RESTRICTION      0xC000006C
310
#define STATUS_LOGON_FAILURE             0xC000006D
311
#define STATUS_ACCOUNT_RESTRICTION       0xC000006E
312
#define STATUS_INVALID_LOGON_HOURS       0xC000006F
313
#define STATUS_INVALID_WORKSTATION       0xC0000070
314
#define STATUS_PASSWORD_EXPIRED          0xC0000071
315
#define STATUS_ACCOUNT_DISABLED          0xC0000072
316
#define STATUS_NONE_MAPPED               0xC0000073
317
#define STATUS_TOO_MANY_LUIDS_REQUESTED  0xC0000074
318
#define STATUS_LUIDS_EXHAUSTED           0xC0000075
319
#define STATUS_INVALID_SUB_AUTHORITY     0xC0000076
320
#define STATUS_INVALID_ACL               0xC0000077
321
#define STATUS_INVALID_SID               0xC0000078
322
#define STATUS_INVALID_SECURITY_DESCR    0xC0000079
323
#define STATUS_PROCEDURE_NOT_FOUND       0xC000007A
324
#define STATUS_INVALID_IMAGE_FORMAT      0xC000007B
325
#define STATUS_NO_TOKEN                  0xC000007C
326
#define STATUS_BAD_INHERITANCE_ACL       0xC000007D
327
#define STATUS_RANGE_NOT_LOCKED          0xC000007E
328
#define STATUS_DISK_FULL                 0xC000007F
329
#define STATUS_SERVER_DISABLED           0xC0000080
330
#define STATUS_SERVER_NOT_DISABLED       0xC0000081
331
#define STATUS_TOO_MANY_GUIDS_REQUESTED  0xC0000082
332
#define STATUS_GUIDS_EXHAUSTED           0xC0000083
333
#define STATUS_INVALID_ID_AUTHORITY      0xC0000084
334
#define STATUS_AGENTS_EXHAUSTED          0xC0000085
335
#define STATUS_INVALID_VOLUME_LABEL      0xC0000086
336
#define STATUS_SECTION_NOT_EXTENDED      0xC0000087
337
#define STATUS_NOT_MAPPED_DATA           0xC0000088
338
#define STATUS_RESOURCE_DATA_NOT_FOUND   0xC0000089
339
#define STATUS_RESOURCE_TYPE_NOT_FOUND   0xC000008A
340
#define STATUS_RESOURCE_NAME_NOT_FOUND   0xC000008B
341
#define STATUS_ARRAY_BOUNDS_EXCEEDED     0xC000008C
342
#define STATUS_FLOAT_DENORMAL_OPERAND    0xC000008D
343
#define STATUS_FLOAT_DIVIDE_BY_ZERO      0xC000008E
344
#define STATUS_FLOAT_INEXACT_RESULT      0xC000008F
345
#define STATUS_FLOAT_INVALID_OPERATION   0xC0000090
346
#define STATUS_FLOAT_OVERFLOW            0xC0000091
347
#define STATUS_FLOAT_STACK_CHECK         0xC0000092
348
#define STATUS_FLOAT_UNDERFLOW           0xC0000093
349
#define STATUS_INTEGER_DIVIDE_BY_ZERO    0xC0000094
350
#define STATUS_INTEGER_OVERFLOW          0xC0000095
351
#define STATUS_PRIVILEGED_INSTRUCTION    0xC0000096
352
#define STATUS_TOO_MANY_PAGING_FILES     0xC0000097
353
#define STATUS_FILE_INVALID              0xC0000098
354
#define STATUS_ALLOTTED_SPACE_EXCEEDED   0xC0000099
355
#define STATUS_INSUFFICIENT_RESOURCES    0xC000009A
356
#define STATUS_DFS_EXIT_PATH_FOUND       0xC000009B
357
#define STATUS_DEVICE_DATA_ERROR         0xC000009C
358
#define STATUS_DEVICE_NOT_CONNECTED      0xC000009D
359
#define STATUS_DEVICE_POWER_FAILURE      0xC000009E
360
#define STATUS_FREE_VM_NOT_AT_BASE       0xC000009F
361
#define STATUS_MEMORY_NOT_ALLOCATED      0xC00000A0
362
#define STATUS_WORKING_SET_QUOTA         0xC00000A1
363
#define STATUS_MEDIA_WRITE_PROTECTED     0xC00000A2
364
#define STATUS_DEVICE_NOT_READY          0xC00000A3
365
#define STATUS_INVALID_GROUP_ATTRIBUTES  0xC00000A4
366
#define STATUS_BAD_IMPERSONATION_LEVEL   0xC00000A5
367
#define STATUS_CANT_OPEN_ANONYMOUS       0xC00000A6
368
#define STATUS_BAD_VALIDATION_CLASS      0xC00000A7
369
#define STATUS_BAD_TOKEN_TYPE            0xC00000A8
370
#define STATUS_BAD_MASTER_BOOT_RECORD    0xC00000A9
371
#define STATUS_INSTRUCTION_MISALIGNMENT  0xC00000AA
372
#define STATUS_INSTANCE_NOT_AVAILABLE    0xC00000AB
373
#define STATUS_PIPE_NOT_AVAILABLE        0xC00000AC
374
#define STATUS_INVALID_PIPE_STATE        0xC00000AD
375
#define STATUS_PIPE_BUSY                 0xC00000AE
376
#define STATUS_ILLEGAL_FUNCTION          0xC00000AF
377
#define STATUS_PIPE_DISCONNECTED         0xC00000B0
378
#define STATUS_PIPE_CLOSING              0xC00000B1
379
#define STATUS_PIPE_CONNECTED            0xC00000B2
380
#define STATUS_PIPE_LISTENING            0xC00000B3
381
#define STATUS_INVALID_READ_MODE         0xC00000B4
382
#define STATUS_IO_TIMEOUT                0xC00000B5
383
#define STATUS_FILE_FORCED_CLOSED        0xC00000B6
384
#define STATUS_PROFILING_NOT_STARTED     0xC00000B7
385
#define STATUS_PROFILING_NOT_STOPPED     0xC00000B8
386
#define STATUS_COULD_NOT_INTERPRET       0xC00000B9
387
#define STATUS_FILE_IS_A_DIRECTORY       0xC00000BA
388
#define STATUS_NOT_SUPPORTED             0xC00000BB
389
#define STATUS_REMOTE_NOT_LISTENING      0xC00000BC
390
#define STATUS_DUPLICATE_NAME            0xC00000BD
391
#define STATUS_BAD_NETWORK_PATH          0xC00000BE
392
#define STATUS_NETWORK_BUSY              0xC00000BF
393
#define STATUS_DEVICE_DOES_NOT_EXIST     0xC00000C0
394
#define STATUS_TOO_MANY_COMMANDS         0xC00000C1
395
#define STATUS_ADAPTER_HARDWARE_ERROR    0xC00000C2
396
#define STATUS_INVALID_NETWORK_RESPONSE  0xC00000C3
397
#define STATUS_UNEXPECTED_NETWORK_ERROR  0xC00000C4
398
#define STATUS_BAD_REMOTE_ADAPTER        0xC00000C5
399
#define STATUS_PRINT_QUEUE_FULL          0xC00000C6
400
#define STATUS_NO_SPOOL_SPACE            0xC00000C7
401
#define STATUS_PRINT_CANCELLED           0xC00000C8
402
#define STATUS_NETWORK_NAME_DELETED      0xC00000C9
403
#define STATUS_NETWORK_ACCESS_DENIED     0xC00000CA
404
#define STATUS_BAD_DEVICE_TYPE           0xC00000CB
405
#define STATUS_BAD_NETWORK_NAME          0xC00000CC
406
#define STATUS_TOO_MANY_NAMES            0xC00000CD
407
#define STATUS_TOO_MANY_SESSIONS         0xC00000CE
408
#define STATUS_SHARING_PAUSED            0xC00000CF
409
#define STATUS_REQUEST_NOT_ACCEPTED      0xC00000D0
410
#define STATUS_REDIRECTOR_PAUSED         0xC00000D1
411
#define STATUS_NET_WRITE_FAULT           0xC00000D2
412
#define STATUS_PROFILING_AT_LIMIT        0xC00000D3
413
#define STATUS_NOT_SAME_DEVICE           0xC00000D4
414
#define STATUS_FILE_RENAMED              0xC00000D5
415
#define STATUS_VIRTUAL_CIRCUIT_CLOSED    0xC00000D6
416
#define STATUS_NO_SECURITY_ON_OBJECT     0xC00000D7
417
#define STATUS_CANT_WAIT                 0xC00000D8
418
#define STATUS_PIPE_EMPTY                0xC00000D9
419
#define STATUS_CANT_ACCESS_DOMAIN_INFO   0xC00000DA
420
#define STATUS_CANT_TERMINATE_SELF       0xC00000DB
421
#define STATUS_INVALID_SERVER_STATE      0xC00000DC
422
#define STATUS_INVALID_DOMAIN_STATE      0xC00000DD
423
#define STATUS_INVALID_DOMAIN_ROLE       0xC00000DE
424
#define STATUS_NO_SUCH_DOMAIN            0xC00000DF
425
#define STATUS_DOMAIN_EXISTS             0xC00000E0
426
#define STATUS_DOMAIN_LIMIT_EXCEEDED     0xC00000E1
427
#define STATUS_OPLOCK_NOT_GRANTED        0xC00000E2
428
#define STATUS_INVALID_OPLOCK_PROTOCOL   0xC00000E3
429
#define STATUS_INTERNAL_DB_CORRUPTION    0xC00000E4
430
#define STATUS_INTERNAL_ERROR            0xC00000E5
431
#define STATUS_GENERIC_NOT_MAPPED        0xC00000E6
432
#define STATUS_BAD_DESCRIPTOR_FORMAT     0xC00000E7
433
#define STATUS_INVALID_USER_BUFFER       0xC00000E8
434
#define STATUS_UNEXPECTED_IO_ERROR       0xC00000E9
435
#define STATUS_UNEXPECTED_MM_CREATE_ERR  0xC00000EA
436
#define STATUS_UNEXPECTED_MM_MAP_ERROR   0xC00000EB
437
#define STATUS_UNEXPECTED_MM_EXTEND_ERR  0xC00000EC
438
#define STATUS_NOT_LOGON_PROCESS         0xC00000ED
439
#define STATUS_LOGON_SESSION_EXISTS      0xC00000EE
440
#define STATUS_INVALID_PARAMETER_1       0xC00000EF
441
#define STATUS_INVALID_PARAMETER_2       0xC00000F0
442
#define STATUS_INVALID_PARAMETER_3       0xC00000F1
443
#define STATUS_INVALID_PARAMETER_4       0xC00000F2
444
#define STATUS_INVALID_PARAMETER_5       0xC00000F3
445
#define STATUS_INVALID_PARAMETER_6       0xC00000F4
446
#define STATUS_INVALID_PARAMETER_7       0xC00000F5
447
#define STATUS_INVALID_PARAMETER_8       0xC00000F6
448
#define STATUS_INVALID_PARAMETER_9       0xC00000F7
449
#define STATUS_INVALID_PARAMETER_10      0xC00000F8
450
#define STATUS_INVALID_PARAMETER_11      0xC00000F9
451
#define STATUS_INVALID_PARAMETER_12      0xC00000FA
452
#define STATUS_REDIRECTOR_NOT_STARTED    0xC00000FB
453
#define STATUS_REDIRECTOR_STARTED        0xC00000FC
454
#define STATUS_STACK_OVERFLOW            0xC00000FD
455
#define STATUS_NO_SUCH_PACKAGE           0xC00000FE
456
#define STATUS_BAD_FUNCTION_TABLE        0xC00000FF
457
#define STATUS_VARIABLE_NOT_FOUND        0xC0000100
458
#define STATUS_DIRECTORY_NOT_EMPTY       0xC0000101
459
#define STATUS_FILE_CORRUPT_ERROR        0xC0000102
460
#define STATUS_NOT_A_DIRECTORY           0xC0000103
461
#define STATUS_BAD_LOGON_SESSION_STATE   0xC0000104
462
#define STATUS_LOGON_SESSION_COLLISION   0xC0000105
463
#define STATUS_NAME_TOO_LONG             0xC0000106
464
#define STATUS_FILES_OPEN                0xC0000107
465
#define STATUS_CONNECTION_IN_USE         0xC0000108
466
#define STATUS_MESSAGE_NOT_FOUND         0xC0000109
467
#define STATUS_PROCESS_IS_TERMINATING    0xC000010A
468
#define STATUS_INVALID_LOGON_TYPE        0xC000010B
469
#define STATUS_NO_GUID_TRANSLATION       0xC000010C
470
#define STATUS_CANNOT_IMPERSONATE        0xC000010D
471
#define STATUS_IMAGE_ALREADY_LOADED      0xC000010E
472
#define STATUS_ABIOS_NOT_PRESENT         0xC000010F
473
#define STATUS_ABIOS_LID_NOT_EXIST       0xC0000110
474
#define STATUS_ABIOS_LID_ALREADY_OWNED   0xC0000111
475
#define STATUS_ABIOS_NOT_LID_OWNER       0xC0000112
476
#define STATUS_ABIOS_INVALID_COMMAND     0xC0000113
477
#define STATUS_ABIOS_INVALID_LID         0xC0000114
478
#define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE 0xC0000115
479
#define STATUS_ABIOS_INVALID_SELECTOR    0xC0000116
480
#define STATUS_NO_LDT                    0xC0000117
481
#define STATUS_INVALID_LDT_SIZE          0xC0000118
482
#define STATUS_INVALID_LDT_OFFSET        0xC0000119
483
#define STATUS_INVALID_LDT_DESCRIPTOR    0xC000011A
484
#define STATUS_INVALID_IMAGE_NE_FORMAT   0xC000011B
485
#define STATUS_RXACT_INVALID_STATE       0xC000011C
486
#define STATUS_RXACT_COMMIT_FAILURE      0xC000011D
487
#define STATUS_MAPPED_FILE_SIZE_ZERO     0xC000011E
488
#define STATUS_TOO_MANY_OPENED_FILES     0xC000011F
489
#define STATUS_CANCELLED                 0xC0000120
490
#define STATUS_CANNOT_DELETE             0xC0000121
491
#define STATUS_INVALID_COMPUTER_NAME     0xC0000122
492
#define STATUS_FILE_DELETED              0xC0000123
493
#define STATUS_SPECIAL_ACCOUNT           0xC0000124
494
#define STATUS_SPECIAL_GROUP             0xC0000125
495
#define STATUS_SPECIAL_USER              0xC0000126
496
#define STATUS_MEMBERS_PRIMARY_GROUP     0xC0000127
497
#define STATUS_FILE_CLOSED               0xC0000128
498
#define STATUS_TOO_MANY_THREADS          0xC0000129
499
#define STATUS_THREAD_NOT_IN_PROCESS     0xC000012A
500
#define STATUS_TOKEN_ALREADY_IN_USE      0xC000012B
501
#define STATUS_PAGEFILE_QUOTA_EXCEEDED   0xC000012C
502
#define STATUS_COMMITMENT_LIMIT          0xC000012D
503
#define STATUS_INVALID_IMAGE_LE_FORMAT   0xC000012E
504
#define STATUS_INVALID_IMAGE_NOT_MZ      0xC000012F
505
#define STATUS_INVALID_IMAGE_PROTECT     0xC0000130
506
#define STATUS_INVALID_IMAGE_WIN_16      0xC0000131
507
#define STATUS_LOGON_SERVER_CONFLICT     0xC0000132
508
#define STATUS_TIME_DIFFERENCE_AT_DC     0xC0000133
509
#define STATUS_SYNCHRONIZATION_REQUIRED  0xC0000134
510
#define STATUS_DLL_NOT_FOUND             0xC0000135
511
#define STATUS_OPEN_FAILED               0xC0000136
512
#define STATUS_IO_PRIVILEGE_FAILED       0xC0000137
513
#define STATUS_ORDINAL_NOT_FOUND         0xC0000138
514
#define STATUS_ENTRYPOINT_NOT_FOUND      0xC0000139
515
#define STATUS_CONTROL_C_EXIT            0xC000013A
516
#define STATUS_LOCAL_DISCONNECT          0xC000013B
517
#define STATUS_REMOTE_DISCONNECT         0xC000013C
518
#define STATUS_REMOTE_RESOURCES          0xC000013D
519
#define STATUS_LINK_FAILED               0xC000013E
520
#define STATUS_LINK_TIMEOUT              0xC000013F
521
#define STATUS_INVALID_CONNECTION        0xC0000140
522
#define STATUS_INVALID_ADDRESS           0xC0000141
523
#define STATUS_DLL_INIT_FAILED           0xC0000142
524
#define STATUS_MISSING_SYSTEMFILE        0xC0000143
525
#define STATUS_UNHANDLED_EXCEPTION       0xC0000144
526
#define STATUS_APP_INIT_FAILURE          0xC0000145
527
#define STATUS_PAGEFILE_CREATE_FAILED    0xC0000146
528
#define STATUS_NO_PAGEFILE               0xC0000147
529
#define STATUS_INVALID_LEVEL             0xC0000148
530
#define STATUS_WRONG_PASSWORD_CORE       0xC0000149
531
#define STATUS_ILLEGAL_FLOAT_CONTEXT     0xC000014A
532
#define STATUS_PIPE_BROKEN               0xC000014B
533
#define STATUS_REGISTRY_CORRUPT          0xC000014C
534
#define STATUS_REGISTRY_IO_FAILED        0xC000014D
535
#define STATUS_NO_EVENT_PAIR             0xC000014E
536
#define STATUS_UNRECOGNIZED_VOLUME       0xC000014F
537
#define STATUS_SERIAL_NO_DEVICE_INITED   0xC0000150
538
#define STATUS_NO_SUCH_ALIAS             0xC0000151
539
#define STATUS_MEMBER_NOT_IN_ALIAS       0xC0000152
540
#define STATUS_MEMBER_IN_ALIAS           0xC0000153
541
#define STATUS_ALIAS_EXISTS              0xC0000154
542
#define STATUS_LOGON_NOT_GRANTED         0xC0000155
543
#define STATUS_TOO_MANY_SECRETS          0xC0000156
544
#define STATUS_SECRET_TOO_LONG           0xC0000157
545
#define STATUS_INTERNAL_DB_ERROR         0xC0000158
546
#define STATUS_FULLSCREEN_MODE           0xC0000159
547
#define STATUS_TOO_MANY_CONTEXT_IDS      0xC000015A
548
#define STATUS_LOGON_TYPE_NOT_GRANTED    0xC000015B
549
#define STATUS_NOT_REGISTRY_FILE         0xC000015C
550
#define STATUS_NT_CROSS_ENCRYPTION_REQUIRED 0xC000015D
551
#define STATUS_DOMAIN_CTRLR_CONFIG_ERROR 0xC000015E
552
#define STATUS_FT_MISSING_MEMBER         0xC000015F
553
#define STATUS_ILL_FORMED_SERVICE_ENTRY  0xC0000160
554
#define STATUS_ILLEGAL_CHARACTER         0xC0000161
555
#define STATUS_UNMAPPABLE_CHARACTER      0xC0000162
556
#define STATUS_UNDEFINED_CHARACTER       0xC0000163
557
#define STATUS_FLOPPY_VOLUME             0xC0000164
558
#define STATUS_FLOPPY_ID_MARK_NOT_FOUND  0xC0000165
559
#define STATUS_FLOPPY_WRONG_CYLINDER     0xC0000166
560
#define STATUS_FLOPPY_UNKNOWN_ERROR      0xC0000167
561
#define STATUS_FLOPPY_BAD_REGISTERS      0xC0000168
562
#define STATUS_DISK_RECALIBRATE_FAILED   0xC0000169
563
#define STATUS_DISK_OPERATION_FAILED     0xC000016A
564
#define STATUS_DISK_RESET_FAILED         0xC000016B
565
#define STATUS_SHARED_IRQ_BUSY           0xC000016C
566
#define STATUS_FT_ORPHANING              0xC000016D
567
#define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT 0xC000016E
568
569
#define STATUS_PARTITION_FAILURE         0xC0000172
570
#define STATUS_INVALID_BLOCK_LENGTH      0xC0000173
571
#define STATUS_DEVICE_NOT_PARTITIONED    0xC0000174
572
#define STATUS_UNABLE_TO_LOCK_MEDIA      0xC0000175
573
#define STATUS_UNABLE_TO_UNLOAD_MEDIA    0xC0000176
574
#define STATUS_EOM_OVERFLOW              0xC0000177
575
#define STATUS_NO_MEDIA                  0xC0000178
576
#define STATUS_NO_SUCH_MEMBER            0xC000017A
577
#define STATUS_INVALID_MEMBER            0xC000017B
578
#define STATUS_KEY_DELETED               0xC000017C
579
#define STATUS_NO_LOG_SPACE              0xC000017D
580
#define STATUS_TOO_MANY_SIDS             0xC000017E
581
#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC000017F
582
#define STATUS_KEY_HAS_CHILDREN          0xC0000180
583
#define STATUS_CHILD_MUST_BE_VOLATILE    0xC0000181
584
#define STATUS_DEVICE_CONFIGURATION_ERROR 0xC0000182
585
#define STATUS_DRIVER_INTERNAL_ERROR     0xC0000183
586
#define STATUS_INVALID_DEVICE_STATE      0xC0000184
587
#define STATUS_IO_DEVICE_ERROR           0xC0000185
588
#define STATUS_DEVICE_PROTOCOL_ERROR     0xC0000186
589
#define STATUS_BACKUP_CONTROLLER         0xC0000187
590
#define STATUS_LOG_FILE_FULL             0xC0000188
591
#define STATUS_TOO_LATE                  0xC0000189
592
#define STATUS_NO_TRUST_LSA_SECRET       0xC000018A
593
#define STATUS_NO_TRUST_SAM_ACCOUNT      0xC000018B
594
#define STATUS_TRUSTED_DOMAIN_FAILURE    0xC000018C
595
#define STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC000018D
596
#define STATUS_EVENTLOG_FILE_CORRUPT     0xC000018E
597
#define STATUS_EVENTLOG_CANT_START       0xC000018F
598
#define STATUS_TRUST_FAILURE             0xC0000190
599
#define STATUS_MUTANT_LIMIT_EXCEEDED     0xC0000191
600
#define STATUS_NETLOGON_NOT_STARTED      0xC0000192
601
#define STATUS_ACCOUNT_EXPIRED           0xC0000193
602
#define STATUS_POSSIBLE_DEADLOCK         0xC0000194
603
#define STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000195
604
#define STATUS_REMOTE_SESSION_LIMIT      0xC0000196
605
#define STATUS_EVENTLOG_FILE_CHANGED     0xC0000197
606
#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000198
607
#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000199
608
#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC000019A
609
#define STATUS_DOMAIN_TRUST_INCONSISTENT 0xC000019B
610
#define STATUS_FS_DRIVER_REQUIRED        0xC000019C
611
#define STATUS_NO_USER_SESSION_KEY       0xC0000202
612
#define STATUS_USER_SESSION_DELETED      0xC0000203
613
#define STATUS_RESOURCE_LANG_NOT_FOUND   0xC0000204
614
#define STATUS_INSUFF_SERVER_RESOURCES   0xC0000205
615
#define STATUS_INVALID_BUFFER_SIZE       0xC0000206
616
#define STATUS_INVALID_ADDRESS_COMPONENT 0xC0000207
617
#define STATUS_INVALID_ADDRESS_WILDCARD  0xC0000208
618
#define STATUS_TOO_MANY_ADDRESSES        0xC0000209
619
#define STATUS_ADDRESS_ALREADY_EXISTS    0xC000020A
620
#define STATUS_ADDRESS_CLOSED            0xC000020B
621
#define STATUS_CONNECTION_DISCONNECTED   0xC000020C
622
#define STATUS_CONNECTION_RESET          0xC000020D
623
#define STATUS_TOO_MANY_NODES            0xC000020E
624
#define STATUS_TRANSACTION_ABORTED       0xC000020F
625
#define STATUS_TRANSACTION_TIMED_OUT     0xC0000210
626
#define STATUS_TRANSACTION_NO_RELEASE    0xC0000211
627
#define STATUS_TRANSACTION_NO_MATCH      0xC0000212
628
#define STATUS_TRANSACTION_RESPONDED     0xC0000213
629
#define STATUS_TRANSACTION_INVALID_ID    0xC0000214
630
#define STATUS_TRANSACTION_INVALID_TYPE  0xC0000215
631
#define STATUS_NOT_SERVER_SESSION        0xC0000216
632
#define STATUS_NOT_CLIENT_SESSION        0xC0000217
633
#define STATUS_CANNOT_LOAD_REGISTRY_FILE 0xC0000218
634
#define STATUS_DEBUG_ATTACH_FAILED       0xC0000219
635
#define STATUS_SYSTEM_PROCESS_TERMINATED 0xC000021A
636
#define STATUS_DATA_NOT_ACCEPTED         0xC000021B
637
#define STATUS_NO_BROWSER_SERVERS_FOUND  0xC000021C
638
#define STATUS_VDM_HARD_ERROR            0xC000021D
639
#define STATUS_DRIVER_CANCEL_TIMEOUT     0xC000021E
640
#define STATUS_REPLY_MESSAGE_MISMATCH    0xC000021F
641
#define STATUS_MAPPED_ALIGNMENT          0xC0000220
642
#define STATUS_IMAGE_CHECKSUM_MISMATCH   0xC0000221
643
#define STATUS_LOST_WRITEBEHIND_DATA     0xC0000222
644
#define STATUS_CLIENT_SERVER_PARAMETERS_INVALID 0xC0000223
645
#define STATUS_PASSWORD_MUST_CHANGE      0xC0000224
646
#define STATUS_NOT_FOUND                 0xC0000225
647
#define STATUS_NOT_TINY_STREAM           0xC0000226
648
#define STATUS_RECOVERY_FAILURE          0xC0000227
649
#define STATUS_STACK_OVERFLOW_READ       0xC0000228
650
#define STATUS_FAIL_CHECK                0xC0000229
651
#define STATUS_DUPLICATE_OBJECTID        0xC000022A
652
#define STATUS_OBJECTID_EXISTS           0xC000022B
653
#define STATUS_CONVERT_TO_LARGE          0xC000022C
654
#define STATUS_RETRY                     0xC000022D
655
#define STATUS_FOUND_OUT_OF_SCOPE        0xC000022E
656
#define STATUS_ALLOCATE_BUCKET           0xC000022F
657
#define STATUS_PROPSET_NOT_FOUND         0xC0000230
658
#define STATUS_MARSHALL_OVERFLOW         0xC0000231
659
#define STATUS_INVALID_VARIANT           0xC0000232
660
#define STATUS_DOMAIN_CONTROLLER_NOT_FOUND 0xC0000233
661
#define STATUS_ACCOUNT_LOCKED_OUT        0xC0000234
662
#define STATUS_HANDLE_NOT_CLOSABLE       0xC0000235
663
#define STATUS_CONNECTION_REFUSED        0xC0000236
664
#define STATUS_GRACEFUL_DISCONNECT       0xC0000237
665
#define STATUS_ADDRESS_ALREADY_ASSOCIATED 0xC0000238
666
#define STATUS_ADDRESS_NOT_ASSOCIATED    0xC0000239
667
#define STATUS_CONNECTION_INVALID        0xC000023A
668
#define STATUS_CONNECTION_ACTIVE         0xC000023B
669
#define STATUS_NETWORK_UNREACHABLE       0xC000023C
670
#define STATUS_HOST_UNREACHABLE          0xC000023D
671
#define STATUS_PROTOCOL_UNREACHABLE      0xC000023E
672
#define STATUS_PORT_UNREACHABLE          0xC000023F
673
#define STATUS_REQUEST_ABORTED           0xC0000240
674
#define STATUS_CONNECTION_ABORTED        0xC0000241
675
#define STATUS_BAD_COMPRESSION_BUFFER    0xC0000242
676
#define STATUS_USER_MAPPED_FILE          0xC0000243
677
#define STATUS_AUDIT_FAILED              0xC0000244
678
#define STATUS_TIMER_RESOLUTION_NOT_SET  0xC0000245
679
#define STATUS_CONNECTION_COUNT_LIMIT    0xC0000246
680
#define STATUS_LOGIN_TIME_RESTRICTION    0xC0000247
681
#define STATUS_LOGIN_WKSTA_RESTRICTION   0xC0000248
682
#define STATUS_IMAGE_MP_UP_MISMATCH      0xC0000249
683
#define STATUS_INSUFFICIENT_LOGON_INFO   0xC0000250
684
#define STATUS_BAD_DLL_ENTRYPOINT        0xC0000251
685
#define STATUS_BAD_SERVICE_ENTRYPOINT    0xC0000252
686
#define STATUS_LPC_REPLY_LOST            0xC0000253
687
#define STATUS_IP_ADDRESS_CONFLICT1      0xC0000254
688
#define STATUS_IP_ADDRESS_CONFLICT2      0xC0000255
689
#define STATUS_REGISTRY_QUOTA_LIMIT      0xC0000256
690
#define STATUS_PATH_NOT_COVERED          0xC0000257
691
#define STATUS_NO_CALLBACK_ACTIVE        0xC0000258
692
#define STATUS_LICENSE_QUOTA_EXCEEDED    0xC0000259
693
#define STATUS_PWD_TOO_SHORT             0xC000025A
694
#define STATUS_PWD_TOO_RECENT            0xC000025B
695
#define STATUS_PWD_HISTORY_CONFLICT      0xC000025C
696
#define STATUS_PLUGPLAY_NO_DEVICE        0xC000025E
697
#define STATUS_UNSUPPORTED_COMPRESSION   0xC000025F
698
#define STATUS_INVALID_HW_PROFILE        0xC0000260
699
#define STATUS_INVALID_PLUGPLAY_DEVICE_PATH 0xC0000261
700
#define STATUS_DRIVER_ORDINAL_NOT_FOUND  0xC0000262
701
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND 0xC0000263
702
#define STATUS_RESOURCE_NOT_OWNED        0xC0000264
703
#define STATUS_TOO_MANY_LINKS            0xC0000265
704
#define STATUS_QUOTA_LIST_INCONSISTENT   0xC0000266
705
#define STATUS_FILE_IS_OFFLINE           0xC0000267
706
#define STATUS_EVALUATION_EXPIRATION     0xC0000268
707
#define STATUS_ILLEGAL_DLL_RELOCATION    0xC0000269
708
#define STATUS_LICENSE_VIOLATION         0xC000026A
709
#define STATUS_DLL_INIT_FAILED_LOGOFF    0xC000026B
710
#define STATUS_DRIVER_UNABLE_TO_LOAD     0xC000026C
711
#define STATUS_DFS_UNAVAILABLE           0xC000026D
712
#define STATUS_VOLUME_DISMOUNTED         0xC000026E
713
#define STATUS_WX86_INTERNAL_ERROR       0xC000026F
714
#define STATUS_WX86_FLOAT_STACK_CHECK    0xC0000270
715
#define STATUS_VALIDATE_CONTINUE         0xC0000271
716
#define STATUS_NO_MATCH                  0xC0000272
717
#define STATUS_NO_MORE_MATCHES           0xC0000273
718
#define STATUS_NOT_A_REPARSE_POINT       0xC0000275
719
#define STATUS_IO_REPARSE_TAG_INVALID    0xC0000276
720
#define STATUS_IO_REPARSE_TAG_MISMATCH   0xC0000277
721
#define STATUS_IO_REPARSE_DATA_INVALID   0xC0000278
722
#define STATUS_IO_REPARSE_TAG_NOT_HANDLED       0xC0000279
723
#define STATUS_REPARSE_POINT_NOT_RESOLVED       0xC0000280
724
#define STATUS_DIRECTORY_IS_A_REPARSE_POINT     0xC0000281
725
#define STATUS_RANGE_LIST_CONFLICT       0xC0000282
726
#define STATUS_SOURCE_ELEMENT_EMPTY      0xC0000283
727
#define STATUS_DESTINATION_ELEMENT_FULL  0xC0000284
728
#define STATUS_ILLEGAL_ELEMENT_ADDRESS   0xC0000285
729
#define STATUS_MAGAZINE_NOT_PRESENT      0xC0000286
730
#define STATUS_REINITIALIZATION_NEEDED   0xC0000287
731
#define STATUS_ENCRYPTION_FAILED         0xC000028A
732
#define STATUS_DECRYPTION_FAILED         0xC000028B
733
#define STATUS_RANGE_NOT_FOUND           0xC000028C
734
#define STATUS_NO_RECOVERY_POLICY        0xC000028D
735
#define STATUS_NO_EFS                    0xC000028E
736
#define STATUS_WRONG_EFS                 0xC000028F
737
#define STATUS_NO_USER_KEYS              0xC0000290
738
#define STATUS_FILE_NOT_ENCRYPTED        0xC0000291
739
#define STATUS_NOT_EXPORT_FORMAT         0xC0000292
740
#define STATUS_FILE_ENCRYPTED            0xC0000293
741
#define STATUS_WMI_GUID_NOT_FOUND        0xC0000295
742
#define STATUS_WMI_INSTANCE_NOT_FOUND    0xC0000296
743
#define STATUS_WMI_ITEMID_NOT_FOUND      0xC0000297
744
#define STATUS_WMI_TRY_AGAIN             0xC0000298
745
#define STATUS_SHARED_POLICY             0xC0000299
746
#define STATUS_POLICY_OBJECT_NOT_FOUND   0xC000029A
747
#define STATUS_POLICY_ONLY_IN_DS         0xC000029B
748
#define STATUS_VOLUME_NOT_UPGRADED       0xC000029C
749
#define STATUS_REMOTE_STORAGE_NOT_ACTIVE 0xC000029D
750
#define STATUS_REMOTE_STORAGE_MEDIA_ERROR       0xC000029E
751
#define STATUS_NO_TRACKING_SERVICE       0xC000029F
752
#define STATUS_SERVER_SID_MISMATCH       0xC00002A0
753
#define STATUS_DS_NO_ATTRIBUTE_OR_VALUE  0xC00002A1
754
#define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX      0xC00002A2
755
#define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED      0xC00002A3
756
#define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS     0xC00002A4
757
#define STATUS_DS_BUSY                   0xC00002A5
758
#define STATUS_DS_UNAVAILABLE            0xC00002A6
759
#define STATUS_DS_NO_RIDS_ALLOCATED      0xC00002A7
760
#define STATUS_DS_NO_MORE_RIDS           0xC00002A8
761
#define STATUS_DS_INCORRECT_ROLE_OWNER   0xC00002A9
762
#define STATUS_DS_RIDMGR_INIT_ERROR      0xC00002AA
763
#define STATUS_DS_OBJ_CLASS_VIOLATION    0xC00002AB
764
#define STATUS_DS_CANT_ON_NON_LEAF       0xC00002AC
765
#define STATUS_DS_CANT_ON_RDN            0xC00002AD
766
#define STATUS_DS_CANT_MOD_OBJ_CLASS     0xC00002AE
767
#define STATUS_DS_CROSS_DOM_MOVE_FAILED  0xC00002AF
768
#define STATUS_DS_GC_NOT_AVAILABLE       0xC00002B0
769
#define STATUS_DIRECTORY_SERVICE_REQUIRED       0xC00002B1
770
#define STATUS_REPARSE_ATTRIBUTE_CONFLICT       0xC00002B2
771
#define STATUS_CANT_ENABLE_DENY_ONLY     0xC00002B3
772
#define STATUS_FLOAT_MULTIPLE_FAULTS     0xC00002B4
773
#define STATUS_FLOAT_MULTIPLE_TRAPS      0xC00002B5
774
#define STATUS_DEVICE_REMOVED            0xC00002B6
775
#define STATUS_JOURNAL_DELETE_IN_PROGRESS       0xC00002B7
776
#define STATUS_JOURNAL_NOT_ACTIVE        0xC00002B8
777
#define STATUS_NOINTERFACE               0xC00002B9
778
#define STATUS_DS_ADMIN_LIMIT_EXCEEDED   0xC00002C1
779
#define STATUS_DRIVER_FAILED_SLEEP       0xC00002C2
780
#define STATUS_MUTUAL_AUTHENTICATION_FAILED     0xC00002C3
781
#define STATUS_CORRUPT_SYSTEM_FILE       0xC00002C4
782
#define STATUS_DATATYPE_MISALIGNMENT_ERROR      0xC00002C5
783
#define STATUS_WMI_READ_ONLY             0xC00002C6
784
#define STATUS_WMI_SET_FAILURE           0xC00002C7
785
#define STATUS_COMMITMENT_MINIMUM        0xC00002C8
786
#define STATUS_REG_NAT_CONSUMPTION       0xC00002C9
787
#define STATUS_TRANSPORT_FULL            0xC00002CA
788
#define STATUS_DS_SAM_INIT_FAILURE       0xC00002CB
789
#define STATUS_ONLY_IF_CONNECTED         0xC00002CC
790
#define STATUS_DS_SENSITIVE_GROUP_VIOLATION     0xC00002CD
791
#define STATUS_PNP_RESTART_ENUMERATION   0xC00002CE
792
#define STATUS_JOURNAL_ENTRY_DELETED     0xC00002CF
793
#define STATUS_DS_CANT_MOD_PRIMARYGROUPID       0xC00002D0
794
#define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE 0xC00002D1
795
#define STATUS_PNP_REBOOT_REQUIRED       0xC00002D2
796
#define STATUS_POWER_STATE_INVALID       0xC00002D3
797
#define STATUS_DS_INVALID_GROUP_TYPE     0xC00002D4
798
#define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN    0xC00002D5
799
#define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN     0xC00002D6
800
#define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 0xC00002D7
801
#define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER     0xC00002D8
802
#define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER      0xC00002D9
803
#define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER   0xC00002DA
804
#define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER      0xC00002DB
805
#define STATUS_DS_HAVE_PRIMARY_MEMBERS   0xC00002DC
806
#define STATUS_WMI_NOT_SUPPORTED         0xC00002DD
807
#define STATUS_INSUFFICIENT_POWER        0xC00002DE
808
#define STATUS_SAM_NEED_BOOTKEY_PASSWORD 0xC00002DF
809
#define STATUS_SAM_NEED_BOOTKEY_FLOPPY   0xC00002E0
810
#define STATUS_DS_CANT_START             0xC00002E1
811
#define STATUS_DS_INIT_FAILURE           0xC00002E2
812
#define STATUS_SAM_INIT_FAILURE          0xC00002E3
813
#define STATUS_DS_GC_REQUIRED            0xC00002E4
814
#define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY    0xC00002E5
815
#define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS    0xC00002E6
816
#define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED        0xC00002E7
817
#define STATUS_MULTIPLE_FAULT_VIOLATION  0xC00002E8
818
#define STATUS_CURRENT_DOMAIN_NOT_ALLOWED       0xC00002E9
819
#define STATUS_CANNOT_MAKE               0xC00002EA
820
#define STATUS_SYSTEM_SHUTDOWN           0xC00002EB
821
#define STATUS_DS_INIT_FAILURE_CONSOLE   0xC00002EC
822
#define STATUS_DS_SAM_INIT_FAILURE_CONSOLE      0xC00002ED
823
#define STATUS_UNFINISHED_CONTEXT_DELETED       0xC00002EE
824
#define STATUS_NO_TGT_REPLY              0xC00002EF
825
#define STATUS_OBJECTID_NOT_FOUND        0xC00002F0
826
#define STATUS_NO_IP_ADDRESSES           0xC00002F1
827
#define STATUS_WRONG_CREDENTIAL_HANDLE   0xC00002F2
828
#define STATUS_CRYPTO_SYSTEM_INVALID     0xC00002F3
829
#define STATUS_MAX_REFERRALS_EXCEEDED    0xC00002F4
830
#define STATUS_MUST_BE_KDC               0xC00002F5
831
#define STATUS_STRONG_CRYPTO_NOT_SUPPORTED      0xC00002F6
832
#define STATUS_TOO_MANY_PRINCIPALS       0xC00002F7
833
#define STATUS_NO_PA_DATA                0xC00002F8
834
#define STATUS_PKINIT_NAME_MISMATCH      0xC00002F9
835
#define STATUS_SMARTCARD_LOGON_REQUIRED  0xC00002FA
836
#define STATUS_KDC_INVALID_REQUEST       0xC00002FB
837
#define STATUS_KDC_UNABLE_TO_REFER       0xC00002FC
838
#define STATUS_KDC_UNKNOWN_ETYPE         0xC00002FD
839
#define STATUS_SHUTDOWN_IN_PROGRESS      0xC00002FE
840
#define STATUS_SERVER_SHUTDOWN_IN_PROGRESS      0xC00002FF
841
#define STATUS_NOT_SUPPORTED_ON_SBS      0xC0000300
842
#define STATUS_WMI_GUID_DISCONNECTED     0xC0000301
843
#define STATUS_WMI_ALREADY_DISABLED      0xC0000302
844
#define STATUS_WMI_ALREADY_ENABLED       0xC0000303
845
#define STATUS_MFT_TOO_FRAGMENTED        0xC0000304
846
#define STATUS_COPY_PROTECTION_FAILURE   0xC0000305
847
#define STATUS_CSS_AUTHENTICATION_FAILURE       0xC0000306
848
#define STATUS_CSS_KEY_NOT_PRESENT       0xC0000307
849
#define STATUS_CSS_KEY_NOT_ESTABLISHED   0xC0000308
850
#define STATUS_CSS_SCRAMBLED_SECTOR      0xC0000309
851
#define STATUS_CSS_REGION_MISMATCH       0xC000030A
852
#define STATUS_CSS_RESETS_EXHAUSTED      0xC000030B
853
#define STATUS_PKINIT_FAILURE            0xC0000320
854
#define STATUS_SMARTCARD_SUBSYSTEM_FAILURE      0xC0000321
855
#define STATUS_NO_KERB_KEY               0xC0000322
856
#define STATUS_HOST_DOWN                 0xC0000350
857
#define STATUS_UNSUPPORTED_PREAUTH       0xC0000351
858
#define STATUS_EFS_ALG_BLOB_TOO_BIG      0xC0000352
859
#define STATUS_PORT_NOT_SET              0xC0000353
860
#define STATUS_DEBUGGER_INACTIVE         0xC0000354
861
#define STATUS_DS_VERSION_CHECK_FAILURE  0xC0000355
862
#define STATUS_AUDITING_DISABLED         0xC0000356
863
#define STATUS_PRENT4_MACHINE_ACCOUNT    0xC0000357
864
#define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER 0xC0000358
865
#define STATUS_INVALID_IMAGE_WIN_32      0xC0000359
866
#define STATUS_INVALID_IMAGE_WIN_64      0xC000035A
867
#define STATUS_BAD_BINDINGS              0xC000035B
868
#define STATUS_NETWORK_SESSION_EXPIRED   0xC000035C
869
#define STATUS_APPHELP_BLOCK             0xC000035D
870
#define STATUS_ALL_SIDS_FILTERED         0xC000035E
871
#define STATUS_NOT_SAFE_MODE_DRIVER      0xC000035F
872
#define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT        0xC0000361
873
#define STATUS_ACCESS_DISABLED_BY_POLICY_PATH   0xC0000362
874
#define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER      0xC0000363
875
#define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER  0xC0000364
876
#define STATUS_FAILED_DRIVER_ENTRY       0xC0000365
877
#define STATUS_DEVICE_ENUMERATION_ERROR  0xC0000366
878
#define STATUS_WAIT_FOR_OPLOCK           0xC0000367
879
#define STATUS_MOUNT_POINT_NOT_RESOLVED  0xC0000368
880
#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER 0xC0000369
881
#define STATUS_MCA_OCCURED               0xC000036A
882
#define STATUS_DRIVER_BLOCKED_CRITICAL   0xC000036B
883
#define STATUS_DRIVER_BLOCKED            0xC000036C
884
#define STATUS_DRIVER_DATABASE_ERROR     0xC000036D
885
#define STATUS_SYSTEM_HIVE_TOO_LARGE     0xC000036E
886
#define STATUS_INVALID_IMPORT_OF_NON_DLL 0xC000036F
887
#define STATUS_SMARTCARD_WRONG_PIN       0xC0000380
888
#define STATUS_SMARTCARD_CARD_BLOCKED    0xC0000381
889
#define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED 0xC0000382
890
#define STATUS_SMARTCARD_NO_CARD         0xC0000383
891
#define STATUS_SMARTCARD_NO_KEY_CONTAINER       0xC0000384
892
#define STATUS_SMARTCARD_NO_CERTIFICATE  0xC0000385
893
#define STATUS_SMARTCARD_NO_KEYSET       0xC0000386
894
#define STATUS_SMARTCARD_IO_ERROR        0xC0000387
895
#define STATUS_DOWNGRADE_DETECTED        0xC0000388
896
#define STATUS_SMARTCARD_CERT_REVOKED    0xC0000389
897
#define STATUS_ISSUING_CA_UNTRUSTED      0xC000038A
898
#define STATUS_REVOCATION_OFFLINE_C      0xC000038B
899
#define STATUS_PKINIT_CLIENT_FAILURE     0xC000038C
900
#define STATUS_SMARTCARD_CERT_EXPIRED    0xC000038D
901
#define STATUS_DRIVER_FAILED_PRIOR_UNLOAD 0xC000038E
902
#define STATUS_SMARTCARD_SILENT_CONTEXT  0xC000038F
903
#define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED 0xC0000401
904
#define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED 0xC0000402
905
#define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED 0xC0000403
906
#define STATUS_DS_NAME_NOT_UNIQUE        0xC0000404
907
#define STATUS_DS_DUPLICATE_ID_FOUND     0xC0000405
908
#define STATUS_DS_GROUP_CONVERSION_ERROR 0xC0000406
909
#define STATUS_VOLSNAP_PREPARE_HIBERNATE 0xC0000407
910
#define STATUS_USER2USER_REQUIRED        0xC0000408
911
#define STATUS_STACK_BUFFER_OVERRUN      0xC0000409
912
#define STATUS_NO_S4U_PROT_SUPPORT       0xC000040A
913
#define STATUS_CROSSREALM_DELEGATION_FAILURE 0xC000040B
914
#define STATUS_REVOCATION_OFFLINE_KDC    0xC000040C
915
#define STATUS_ISSUING_CA_UNTRUSTED_KDC  0xC000040D
916
#define STATUS_KDC_CERT_EXPIRED          0xC000040E
917
#define STATUS_KDC_CERT_REVOKED          0xC000040F
918
#define STATUS_PARAMETER_QUOTA_EXCEEDED  0xC0000410
919
#define STATUS_HIBERNATION_FAILURE       0xC0000411
920
#define STATUS_DELAY_LOAD_FAILED         0xC0000412
921
#define STATUS_AUTHENTICATION_FIREWALL_FAILED 0xC0000413
922
#define STATUS_VDM_DISALLOWED            0xC0000414
923
#define STATUS_HUNG_DISPLAY_DRIVER_THREAD 0xC0000415
924
#define STATUS_WOW_ASSERTION             0xC0009898
925
926
#define RPC_NT_INVALID_STRING_BINDING    0xC0020001
927
#define RPC_NT_WRONG_KIND_OF_BINDING     0xC0020002
928
#define RPC_NT_INVALID_BINDING           0xC0020003
929
#define RPC_NT_PROTSEQ_NOT_SUPPORTED     0xC0020004
930
#define RPC_NT_INVALID_RPC_PROTSEQ       0xC0020005
931
#define RPC_NT_INVALID_STRING_UUID       0xC0020006
932
#define RPC_NT_INVALID_ENDPOINT_FORMAT   0xC0020007
933
#define RPC_NT_INVALID_NET_ADDR          0xC0020008
934
#define RPC_NT_NO_ENDPOINT_FOUND         0xC0020009
935
#define RPC_NT_INVALID_TIMEOUT           0xC002000A
936
#define RPC_NT_OBJECT_NOT_FOUND          0xC002000B
937
#define RPC_NT_ALREADY_REGISTERED        0xC002000C
938
#define RPC_NT_TYPE_ALREADY_REGISTERED   0xC002000D
939
#define RPC_NT_ALREADY_LISTENING         0xC002000E
940
#define RPC_NT_NO_PROTSEQS_REGISTERED    0xC002000F
941
#define RPC_NT_NOT_LISTENING             0xC0020010
942
#define RPC_NT_UNKNOWN_MGR_TYPE          0xC0020011
943
#define RPC_NT_UNKNOWN_IF                0xC0020012
944
#define RPC_NT_NO_BINDINGS               0xC0020013
945
#define RPC_NT_NO_PROTSEQS               0xC0020014
946
#define RPC_NT_CANT_CREATE_ENDPOINT      0xC0020015
947
#define RPC_NT_OUT_OF_RESOURCES          0xC0020016
948
#define RPC_NT_SERVER_UNAVAILABLE        0xC0020017
949
#define RPC_NT_SERVER_TOO_BUSY           0xC0020018
950
#define RPC_NT_INVALID_NETWORK_OPTIONS   0xC0020019
951
#define RPC_NT_NO_CALL_ACTIVE            0xC002001A
952
#define RPC_NT_CALL_FAILED               0xC002001B
953
#define RPC_NT_CALL_FAILED_DNE           0xC002001C
954
#define RPC_NT_PROTOCOL_ERROR            0xC002001D
955
#define RPC_NT_UNSUPPORTED_TRANS_SYN     0xC002001F
956
#define RPC_NT_UNSUPPORTED_TYPE          0xC0020021
957
#define RPC_NT_INVALID_TAG               0xC0020022
958
#define RPC_NT_INVALID_BOUND             0xC0020023
959
#define RPC_NT_NO_ENTRY_NAME             0xC0020024
960
#define RPC_NT_INVALID_NAME_SYNTAX       0xC0020025
961
#define RPC_NT_UNSUPPORTED_NAME_SYNTAX   0xC0020026
962
#define RPC_NT_UUID_NO_ADDRESS           0xC0020028
963
#define RPC_NT_DUPLICATE_ENDPOINT        0xC0020029
964
#define RPC_NT_UNKNOWN_AUTHN_TYPE        0xC002002A
965
#define RPC_NT_MAX_CALLS_TOO_SMALL       0xC002002B
966
#define RPC_NT_STRING_TOO_LONG           0xC002002C
967
#define RPC_NT_PROTSEQ_NOT_FOUND         0xC002002D
968
#define RPC_NT_PROCNUM_OUT_OF_RANGE      0xC002002E
969
#define RPC_NT_BINDING_HAS_NO_AUTH       0xC002002F
970
#define RPC_NT_UNKNOWN_AUTHN_SERVICE     0xC0020030
971
#define RPC_NT_UNKNOWN_AUTHN_LEVEL       0xC0020031
972
#define RPC_NT_INVALID_AUTH_IDENTITY     0xC0020032
973
#define RPC_NT_UNKNOWN_AUTHZ_SERVICE     0xC0020033
974
#define EPT_NT_INVALID_ENTRY             0xC0020034
975
#define EPT_NT_CANT_PERFORM_OP           0xC0020035
976
#define EPT_NT_NOT_REGISTERED            0xC0020036
977
#define RPC_NT_NOTHING_TO_EXPORT         0xC0020037
978
#define RPC_NT_INCOMPLETE_NAME           0xC0020038
979
#define RPC_NT_INVALID_VERS_OPTION       0xC0020039
980
#define RPC_NT_NO_MORE_MEMBERS           0xC002003A
981
#define RPC_NT_NOT_ALL_OBJS_UNEXPORTED   0xC002003B
982
#define RPC_NT_INTERFACE_NOT_FOUND       0xC002003C
983
#define RPC_NT_ENTRY_ALREADY_EXISTS      0xC002003D
984
#define RPC_NT_ENTRY_NOT_FOUND           0xC002003E
985
#define RPC_NT_NAME_SERVICE_UNAVAILABLE  0xC002003F
986
#define RPC_NT_INVALID_NAF_ID            0xC0020040
987
#define RPC_NT_CANNOT_SUPPORT            0xC0020041
988
#define RPC_NT_NO_CONTEXT_AVAILABLE      0xC0020042
989
#define RPC_NT_INTERNAL_ERROR            0xC0020043
990
#define RPC_NT_ZERO_DIVIDE               0xC0020044
991
#define RPC_NT_ADDRESS_ERROR             0xC0020045
992
#define RPC_NT_FP_DIV_ZERO               0xC0020046
993
#define RPC_NT_FP_UNDERFLOW              0xC0020047
994
#define RPC_NT_FP_OVERFLOW               0xC0020048
995
#define RPC_NT_CALL_IN_PROGRESS          0xC0020049
996
#define RPC_NT_NO_MORE_BINDINGS          0xC002004A
997
#define RPC_NT_GROUP_MEMBER_NOT_FOUND    0xC002004B
998
#define EPT_NT_CANT_CREATE               0xC002004C
999
#define RPC_NT_INVALID_OBJECT            0xC002004D
1000
#define RPC_NT_NO_INTERFACES             0xC002004F
1001
#define RPC_NT_CALL_CANCELLED            0xC0020050
1002
#define RPC_NT_BINDING_INCOMPLETE        0xC0020051
1003
#define RPC_NT_COMM_FAILURE              0xC0020052
1004
#define RPC_NT_UNSUPPORTED_AUTHN_LEVEL   0xC0020053
1005
#define RPC_NT_NO_PRINC_NAME             0xC0020054
1006
#define RPC_NT_NOT_RPC_ERROR             0xC0020055
1007
#define RPC_NT_SEC_PKG_ERROR             0xC0020057
1008
#define RPC_NT_NOT_CANCELLED             0xC0020058
1009
#define RPC_NT_INVALID_ASYNC_HANDLE      0xC0020062
1010
#define RPC_NT_INVALID_ASYNC_CALL        0xC0020063
1011
1012
#define RPC_NT_NO_MORE_ENTRIES           0xC0030001
1013
#define RPC_NT_SS_CHAR_TRANS_OPEN_FAIL   0xC0030002
1014
#define RPC_NT_SS_CHAR_TRANS_SHORT_FILE  0xC0030003
1015
#define RPC_NT_SS_IN_NULL_CONTEXT        0xC0030004
1016
#define RPC_NT_SS_CONTEXT_MISMATCH       0xC0030005
1017
#define RPC_NT_SS_CONTEXT_DAMAGED        0xC0030006
1018
#define RPC_NT_SS_HANDLES_MISMATCH       0xC0030007
1019
#define RPC_NT_SS_CANNOT_GET_CALL_HANDLE 0xC0030008
1020
#define RPC_NT_NULL_REF_POINTER          0xC0030009
1021
#define RPC_NT_ENUM_VALUE_OUT_OF_RANGE   0xC003000A
1022
#define RPC_NT_BYTE_COUNT_TOO_SMALL      0xC003000B
1023
#define RPC_NT_BAD_STUB_DATA             0xC003000C
1024
#define RPC_NT_INVALID_ES_ACTION         0xC0030059
1025
#define RPC_NT_WRONG_ES_VERSION          0xC003005A
1026
#define RPC_NT_WRONG_STUB_VERSION        0xC003005B
1027
#define RPC_NT_INVALID_PIPE_OBJECT       0xC003005C
1028
#define RPC_NT_INVALID_PIPE_OPERATION    0xC003005D
1029
#define RPC_NT_WRONG_PIPE_VERSION        0xC003005E
1030
#define RPC_NT_PIPE_CLOSED               0xC003005F
1031
#define RPC_NT_PIPE_DISCIPLINE_ERROR     0xC0030060
1032
#define RPC_NT_PIPE_EMPTY                0xC0030061
1033
1034
#define STATUS_PNP_BAD_MPS_TABLE         0xC0040035
1035
#define STATUS_PNP_TRANSLATION_FAILED    0xC0040036
1036
#define STATUS_PNP_IRQ_TRANSLATION_FAILED 0xC0040037
1037
#define STATUS_PNP_INVALID_ID            0xC0040038
1038
1039
#define STATUS_CTX_WINSTATION_NAME_INVALID      0xC00A0001
1040
#define STATUS_CTX_INVALID_PD            0xC00A0002
1041
#define STATUS_CTX_PD_NOT_FOUND          0xC00A0003
1042
#define STATUS_CTX_CLOSE_PENDING         0xC00A0006
1043
#define STATUS_CTX_NO_OUTBUF             0xC00A0007
1044
#define STATUS_CTX_MODEM_INF_NOT_FOUND   0xC00A0008
1045
#define STATUS_CTX_INVALID_MODEMNAME     0xC00A0009
1046
#define STATUS_CTX_RESPONSE_ERROR        0xC00A000A
1047
#define STATUS_CTX_MODEM_RESPONSE_TIMEOUT       0xC00A000B
1048
#define STATUS_CTX_MODEM_RESPONSE_NO_CARRIER    0xC00A000C
1049
#define STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE   0xC00A000D
1050
#define STATUS_CTX_MODEM_RESPONSE_BUSY   0xC00A000E
1051
#define STATUS_CTX_MODEM_RESPONSE_VOICE  0xC00A000F
1052
#define STATUS_CTX_TD_ERROR              0xC00A0010
1053
#define STATUS_CTX_LICENSE_CLIENT_INVALID       0xC00A0012
1054
#define STATUS_CTX_LICENSE_NOT_AVAILABLE 0xC00A0013
1055
#define STATUS_CTX_LICENSE_EXPIRED       0xC00A0014
1056
#define STATUS_CTX_WINSTATION_NOT_FOUND  0xC00A0015
1057
#define STATUS_CTX_WINSTATION_NAME_COLLISION    0xC00A0016
1058
#define STATUS_CTX_WINSTATION_BUSY       0xC00A0017
1059
#define STATUS_CTX_BAD_VIDEO_MODE        0xC00A0018
1060
#define STATUS_CTX_GRAPHICS_INVALID      0xC00A0022
1061
#define STATUS_CTX_NOT_CONSOLE           0xC00A0024
1062
#define STATUS_CTX_CLIENT_QUERY_TIMEOUT  0xC00A0026
1063
#define STATUS_CTX_CONSOLE_DISCONNECT    0xC00A0027
1064
#define STATUS_CTX_CONSOLE_CONNECT       0xC00A0028
1065
#define STATUS_CTX_SHADOW_DENIED         0xC00A002A
1066
#define STATUS_CTX_WINSTATION_ACCESS_DENIED     0xC00A002B
1067
#define STATUS_CTX_INVALID_WD            0xC00A002E
1068
#define STATUS_CTX_WD_NOT_FOUND          0xC00A002F
1069
#define STATUS_CTX_SHADOW_INVALID        0xC00A0030
1070
#define STATUS_CTX_SHADOW_DISABLED       0xC00A0031
1071
#define STATUS_RDP_PROTOCOL_ERROR        0xC00A0032
1072
#define STATUS_CTX_CLIENT_LICENSE_NOT_SET       0xC00A0033
1073
#define STATUS_CTX_CLIENT_LICENSE_IN_USE 0xC00A0034
1074
#define STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE  0xC00A0035
1075
#define STATUS_CTX_SHADOW_NOT_RUNNING    0xC00A0036
1076
1077
#define STATUS_CLUSTER_INVALID_NODE      0xC0130001
1078
#define STATUS_CLUSTER_NODE_EXISTS       0xC0130002
1079
#define STATUS_CLUSTER_JOIN_IN_PROGRESS  0xC0130003
1080
#define STATUS_CLUSTER_NODE_NOT_FOUND    0xC0130004
1081
#define STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND     0xC0130005
1082
#define STATUS_CLUSTER_NETWORK_EXISTS    0xC0130006
1083
#define STATUS_CLUSTER_NETWORK_NOT_FOUND 0xC0130007
1084
#define STATUS_CLUSTER_NETINTERFACE_EXISTS      0xC0130008
1085
#define STATUS_CLUSTER_NETINTERFACE_NOT_FOUND   0xC0130009
1086
#define STATUS_CLUSTER_INVALID_REQUEST   0xC013000A
1087
#define STATUS_CLUSTER_INVALID_NETWORK_PROVIDER 0xC013000B
1088
#define STATUS_CLUSTER_NODE_DOWN         0xC013000C
1089
#define STATUS_CLUSTER_NODE_UNREACHABLE  0xC013000D
1090
#define STATUS_CLUSTER_NODE_NOT_MEMBER   0xC013000E
1091
#define STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS     0xC013000F
1092
#define STATUS_CLUSTER_INVALID_NETWORK   0xC0130010
1093
#define STATUS_CLUSTER_NO_NET_ADAPTERS   0xC0130011
1094
#define STATUS_CLUSTER_NODE_UP           0xC0130012
1095
#define STATUS_CLUSTER_NODE_PAUSED       0xC0130013
1096
#define STATUS_CLUSTER_NODE_NOT_PAUSED   0xC0130014
1097
#define STATUS_CLUSTER_NO_SECURITY_CONTEXT      0xC0130015
1098
#define STATUS_CLUSTER_NETWORK_NOT_INTERNAL     0xC0130016
1099
#define STATUS_CLUSTER_POISONED          0xC0130017
1100
1101
#define STATUS_SXS_SECTION_NOT_FOUND     0xC0150001
1102
#define STATUS_SXS_CANT_GEN_ACTCTX       0xC0150002
1103
#define STATUS_SXS_INVALID_ACTCTXDATA_FORMAT    0xC0150003
1104
#define STATUS_SXS_ASSEMBLY_NOT_FOUND    0xC0150004
1105
#define STATUS_SXS_MANIFEST_FORMAT_ERROR 0xC0150005
1106
#define STATUS_SXS_MANIFEST_PARSE_ERROR  0xC0150006
1107
#define STATUS_SXS_ACTIVATION_CONTEXT_DISABLED  0xC0150007
1108
#define STATUS_SXS_KEY_NOT_FOUND         0xC0150008
1109
#define STATUS_SXS_VERSION_CONFLICT      0xC0150009
1110
#define STATUS_SXS_WRONG_SECTION_TYPE    0xC015000A
1111
#define STATUS_SXS_THREAD_QUERIES_DISABLED      0xC015000B
1112
#define STATUS_SXS_ASSEMBLY_MISSING      0xC015000C
1113
#define STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET  0xC015000E
1114
#define STATUS_SXS_EARLY_DEACTIVATION    0xC015000F
1115
#define STATUS_SXS_INVALID_DEACTIVATION  0xC0150010
1116
#define STATUS_SXS_MULTIPLE_DEACTIVATION 0xC0150011
1117
#define STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY 0xC0150012
1118
#define STATUS_SXS_PROCESS_TERMINATION_REQUESTED 0xC0150013
1119
#define STATUS_SXS_CORRUPT_ACTIVATION_STACK 0xC0150014
1120
#define STATUS_SXS_CORRUPTION            0xC0150015
1121
1122
#endif /* WIN32_NO_STATUS */
1123
1124
#ifndef __VALUE_STRING_H__
1125
#define __VALUE_STRING_H__
1126
1127
typedef struct _value_string {
1128
  uint32_t				value;
1129
  const char *				strptr;
1130
} value_string;
1131
1132
/*
1133
 * NT error codes.
1134
 *
1135
 * From
1136
 *
1137
 *	http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
1138
 */
1139
static const value_string NT_errors[] = {
1140
  { 0x00000000, "STATUS_SUCCESS" },
1141
  { 0x00000000, "STATUS_WAIT_0" },
1142
  { 0x00000001, "STATUS_WAIT_1" },
1143
  { 0x00000002, "STATUS_WAIT_2" },
1144
  { 0x00000003, "STATUS_WAIT_3" },
1145
  { 0x0000003F, "STATUS_WAIT_63" },
1146
  { 0x00000080, "STATUS_ABANDONED" },
1147
  { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
1148
  { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
1149
  { 0x000000C0, "STATUS_USER_APC" },
1150
  { 0x00000100, "STATUS_KERNEL_APC" },
1151
  { 0x00000101, "STATUS_ALERTED" },
1152
  { 0x00000102, "STATUS_TIMEOUT" },
1153
  { 0x00000103, "STATUS_PENDING" },
1154
  { 0x00000104, "STATUS_REPARSE" },
1155
  { 0x00000105, "STATUS_MORE_ENTRIES" },
1156
  { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
1157
  { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
1158
  { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
1159
  { 0x00000109, "STATUS_VOLUME_MOUNTED" },
1160
  { 0x0000010A, "STATUS_RXACT_COMMITTED" },
1161
  { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
1162
  { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
1163
  { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
1164
  { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
1165
  { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
1166
  { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
1167
  { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
1168
  { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
1169
  { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
1170
  { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
1171
  { 0x00000116, "STATUS_CRASH_DUMP" },
1172
  { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
1173
  { 0x00000118, "STATUS_REPARSE_OBJECT" },
1174
  { 0x0000045C, "STATUS_NO_SHUTDOWN_IN_PROGRESS" },
1175
  { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
1176
  { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
1177
  { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
1178
  { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
1179
  { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
1180
  { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
1181
  { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
1182
  { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
1183
  { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
1184
  { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
1185
  { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
1186
  { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
1187
  { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
1188
  { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
1189
  { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
1190
  { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
1191
  { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
1192
  { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
1193
  { 0x40000012, "STATUS_EVENT_DONE" },
1194
  { 0x40000013, "STATUS_EVENT_PENDING" },
1195
  { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
1196
  { 0x40000015, "STATUS_FATAL_APP_EXIT" },
1197
  { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
1198
  { 0x40000017, "STATUS_WAS_UNLOCKED" },
1199
  { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
1200
  { 0x40000019, "STATUS_WAS_LOCKED" },
1201
  { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
1202
  { 0x4000001B, "STATUS_ALREADY_WIN32" },
1203
  { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
1204
  { 0x4000001D, "STATUS_WX86_CONTINUE" },
1205
  { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
1206
  { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
1207
  { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
1208
  { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
1209
  { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
1210
  { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
1211
  { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
1212
  { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
1213
  { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
1214
  { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
1215
  { 0x80000003, "STATUS_BREAKPOINT" },
1216
  { 0x80000004, "STATUS_SINGLE_STEP" },
1217
  { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
1218
  { 0x80000006, "STATUS_NO_MORE_FILES" },
1219
  { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
1220
  { 0x8000000A, "STATUS_HANDLES_CLOSED" },
1221
  { 0x8000000B, "STATUS_NO_INHERITANCE" },
1222
  { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
1223
  { 0x8000000D, "STATUS_PARTIAL_COPY" },
1224
  { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
1225
  { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
1226
  { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
1227
  { 0x80000011, "STATUS_DEVICE_BUSY" },
1228
  { 0x80000012, "STATUS_NO_MORE_EAS" },
1229
  { 0x80000013, "STATUS_INVALID_EA_NAME" },
1230
  { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
1231
  { 0x80000015, "STATUS_INVALID_EA_FLAG" },
1232
  { 0x80000016, "STATUS_VERIFY_REQUIRED" },
1233
  { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
1234
  { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
1235
  { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
1236
  { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
1237
  { 0x8000001C, "STATUS_MEDIA_CHANGED" },
1238
  { 0x8000001D, "STATUS_BUS_RESET" },
1239
  { 0x8000001E, "STATUS_END_OF_MEDIA" },
1240
  { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
1241
  { 0x80000020, "STATUS_MEDIA_CHECK" },
1242
  { 0x80000021, "STATUS_SETMARK_DETECTED" },
1243
  { 0x80000022, "STATUS_NO_DATA_DETECTED" },
1244
  { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
1245
  { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
1246
  { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
1247
  { 0x80000026, "STATUS_LONGJUMP" },
1248
  { 0x80040111, "MAPI_E_LOGON_FAILED" },
1249
  { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
1250
  { 0x80090301, "SEC_E_INVALID_HANDLE" },
1251
  { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
1252
  { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
1253
  { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
1254
  { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
1255
  { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
1256
  { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
1257
  { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
1258
  { 0xC0000001, "STATUS_UNSUCCESSFUL" },
1259
  { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
1260
  { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
1261
  { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
1262
  { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
1263
  { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
1264
  { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
1265
  { 0xC0000008, "STATUS_INVALID_HANDLE" },
1266
  { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
1267
  { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
1268
  { 0xC000000B, "STATUS_INVALID_CID" },
1269
  { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
1270
  { 0xC000000D, "STATUS_INVALID_PARAMETER" },
1271
  { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
1272
  { 0xC000000F, "STATUS_NO_SUCH_FILE" },
1273
  { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
1274
  { 0xC0000011, "STATUS_END_OF_FILE" },
1275
  { 0xC0000012, "STATUS_WRONG_VOLUME" },
1276
  { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
1277
  { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
1278
  { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
1279
  { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
1280
  { 0xC0000017, "STATUS_NO_MEMORY" },
1281
  { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
1282
  { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
1283
  { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
1284
  { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
1285
  { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
1286
  { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
1287
  { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
1288
  { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
1289
  { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
1290
  { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
1291
  { 0xC0000022, "STATUS_ACCESS_DENIED" },
1292
  { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
1293
  { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
1294
  { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
1295
  { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
1296
  { 0xC0000027, "STATUS_UNWIND" },
1297
  { 0xC0000028, "STATUS_BAD_STACK" },
1298
  { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
1299
  { 0xC000002A, "STATUS_NOT_LOCKED" },
1300
  { 0xC000002B, "STATUS_PARITY_ERROR" },
1301
  { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
1302
  { 0xC000002D, "STATUS_NOT_COMMITTED" },
1303
  { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
1304
  { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
1305
  { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
1306
  { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
1307
  { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
1308
  { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
1309
  { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
1310
  { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
1311
  { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
1312
  { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
1313
  { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
1314
  { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
1315
  { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
1316
  { 0xC000003C, "STATUS_DATA_OVERRUN" },
1317
  { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
1318
  { 0xC000003E, "STATUS_DATA_ERROR" },
1319
  { 0xC000003F, "STATUS_CRC_ERROR" },
1320
  { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
1321
  { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
1322
  { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
1323
  { 0xC0000043, "STATUS_SHARING_VIOLATION" },
1324
  { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
1325
  { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
1326
  { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
1327
  { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
1328
  { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
1329
  { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
1330
  { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
1331
  { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
1332
  { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
1333
  { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
1334
  { 0xC000004E, "STATUS_SECTION_PROTECTION" },
1335
  { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
1336
  { 0xC0000050, "STATUS_EA_TOO_LARGE" },
1337
  { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
1338
  { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
1339
  { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
1340
  { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
1341
  { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
1342
  { 0xC0000056, "STATUS_DELETE_PENDING" },
1343
  { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
1344
  { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
1345
  { 0xC0000059, "STATUS_REVISION_MISMATCH" },
1346
  { 0xC000005A, "STATUS_INVALID_OWNER" },
1347
  { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
1348
  { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
1349
  { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
1350
  { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
1351
  { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
1352
  { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
1353
  { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
1354
  { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
1355
  { 0xC0000063, "STATUS_USER_EXISTS" },
1356
  { 0xC0000064, "STATUS_NO_SUCH_USER" },
1357
  { 0xC0000065, "STATUS_GROUP_EXISTS" },
1358
  { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
1359
  { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
1360
  { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
1361
  { 0xC0000069, "STATUS_LAST_ADMIN" },
1362
  { 0xC000006A, "STATUS_WRONG_PASSWORD" },
1363
  { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
1364
  { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
1365
  { 0xC000006D, "STATUS_LOGON_FAILURE" },
1366
  { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
1367
  { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
1368
  { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
1369
  { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
1370
  { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
1371
  { 0xC0000073, "STATUS_NONE_MAPPED" },
1372
  { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
1373
  { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
1374
  { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
1375
  { 0xC0000077, "STATUS_INVALID_ACL" },
1376
  { 0xC0000078, "STATUS_INVALID_SID" },
1377
  { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
1378
  { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
1379
  { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
1380
  { 0xC000007C, "STATUS_NO_TOKEN" },
1381
  { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
1382
  { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
1383
  { 0xC000007F, "STATUS_DISK_FULL" },
1384
  { 0xC0000080, "STATUS_SERVER_DISABLED" },
1385
  { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
1386
  { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
1387
  { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
1388
  { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
1389
  { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
1390
  { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
1391
  { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
1392
  { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
1393
  { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
1394
  { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
1395
  { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
1396
  { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
1397
  { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
1398
  { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
1399
  { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
1400
  { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
1401
  { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
1402
  { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
1403
  { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
1404
  { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
1405
  { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
1406
  { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
1407
  { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
1408
  { 0xC0000098, "STATUS_FILE_INVALID" },
1409
  { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
1410
  { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
1411
  { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
1412
  { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
1413
  { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
1414
  { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
1415
  { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
1416
  { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
1417
  { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
1418
  { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
1419
  { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
1420
  { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
1421
  { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
1422
  { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
1423
  { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
1424
  { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
1425
  { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
1426
  { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
1427
  { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
1428
  { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
1429
  { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
1430
  { 0xC00000AE, "STATUS_PIPE_BUSY" },
1431
  { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
1432
  { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
1433
  { 0xC00000B1, "STATUS_PIPE_CLOSING" },
1434
  { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
1435
  { 0xC00000B3, "STATUS_PIPE_LISTENING" },
1436
  { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
1437
  { 0xC00000B5, "STATUS_IO_TIMEOUT" },
1438
  { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
1439
  { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
1440
  { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
1441
  { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
1442
  { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
1443
  { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
1444
  { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
1445
  { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
1446
  { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
1447
  { 0xC00000BF, "STATUS_NETWORK_BUSY" },
1448
  { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
1449
  { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
1450
  { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
1451
  { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
1452
  { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
1453
  { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
1454
  { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
1455
  { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
1456
  { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
1457
  { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
1458
  { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
1459
  { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
1460
  { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
1461
  { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
1462
  { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
1463
  { 0xC00000CF, "STATUS_SHARING_PAUSED" },
1464
  { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
1465
  { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
1466
  { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
1467
  { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
1468
  { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
1469
  { 0xC00000D5, "STATUS_FILE_RENAMED" },
1470
  { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
1471
  { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
1472
  { 0xC00000D8, "STATUS_CANT_WAIT" },
1473
  { 0xC00000D9, "STATUS_PIPE_EMPTY" },
1474
  { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
1475
  { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
1476
  { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
1477
  { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
1478
  { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
1479
  { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
1480
  { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
1481
  { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
1482
  { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
1483
  { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
1484
  { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
1485
  { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
1486
  { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
1487
  { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
1488
  { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
1489
  { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
1490
  { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
1491
  { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
1492
  { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
1493
  { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
1494
  { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
1495
  { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
1496
  { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
1497
  { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
1498
  { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
1499
  { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
1500
  { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
1501
  { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
1502
  { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
1503
  { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
1504
  { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
1505
  { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
1506
  { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
1507
  { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
1508
  { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
1509
  { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
1510
  { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
1511
  { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
1512
  { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
1513
  { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
1514
  { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
1515
  { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
1516
  { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
1517
  { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
1518
  { 0xC0000106, "STATUS_NAME_TOO_LONG" },
1519
  { 0xC0000107, "STATUS_FILES_OPEN" },
1520
  { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
1521
  { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
1522
  { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
1523
  { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
1524
  { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
1525
  { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
1526
  { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
1527
  { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
1528
  { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
1529
  { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
1530
  { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
1531
  { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
1532
  { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
1533
  { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
1534
  { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
1535
  { 0xC0000117, "STATUS_NO_LDT" },
1536
  { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
1537
  { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
1538
  { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
1539
  { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
1540
  { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
1541
  { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
1542
  { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
1543
  { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
1544
  { 0xC0000120, "STATUS_CANCELLED" },
1545
  { 0xC0000121, "STATUS_CANNOT_DELETE" },
1546
  { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
1547
  { 0xC0000123, "STATUS_FILE_DELETED" },
1548
  { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
1549
  { 0xC0000125, "STATUS_SPECIAL_GROUP" },
1550
  { 0xC0000126, "STATUS_SPECIAL_USER" },
1551
  { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
1552
  { 0xC0000128, "STATUS_FILE_CLOSED" },
1553
  { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
1554
  { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
1555
  { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
1556
  { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
1557
  { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
1558
  { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
1559
  { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
1560
  { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
1561
  { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
1562
  { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
1563
  { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
1564
  { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
1565
  { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
1566
  { 0xC0000136, "STATUS_OPEN_FAILED" },
1567
  { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
1568
  { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
1569
  { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
1570
  { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
1571
  { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
1572
  { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
1573
  { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
1574
  { 0xC000013E, "STATUS_LINK_FAILED" },
1575
  { 0xC000013F, "STATUS_LINK_TIMEOUT" },
1576
  { 0xC0000140, "STATUS_INVALID_CONNECTION" },
1577
  { 0xC0000141, "STATUS_INVALID_ADDRESS" },
1578
  { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
1579
  { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
1580
  { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
1581
  { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
1582
  { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
1583
  { 0xC0000147, "STATUS_NO_PAGEFILE" },
1584
  { 0xC0000148, "STATUS_INVALID_LEVEL" },
1585
  { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
1586
  { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
1587
  { 0xC000014B, "STATUS_PIPE_BROKEN" },
1588
  { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
1589
  { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
1590
  { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
1591
  { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
1592
  { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
1593
  { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
1594
  { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
1595
  { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
1596
  { 0xC0000154, "STATUS_ALIAS_EXISTS" },
1597
  { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
1598
  { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
1599
  { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
1600
  { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
1601
  { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
1602
  { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
1603
  { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
1604
  { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
1605
  { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
1606
  { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
1607
  { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
1608
  { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
1609
  { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
1610
  { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
1611
  { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
1612
  { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
1613
  { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
1614
  { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
1615
  { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
1616
  { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
1617
  { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
1618
  { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
1619
  { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
1620
  { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
1621
  { 0xC000016D, "STATUS_FT_ORPHANING" },
1622
  { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
1623
  { 0xC0000172, "STATUS_PARTITION_FAILURE" },
1624
  { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
1625
  { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
1626
  { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
1627
  { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
1628
  { 0xC0000177, "STATUS_EOM_OVERFLOW" },
1629
  { 0xC0000178, "STATUS_NO_MEDIA" },
1630
  { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
1631
  { 0xC000017B, "STATUS_INVALID_MEMBER" },
1632
  { 0xC000017C, "STATUS_KEY_DELETED" },
1633
  { 0xC000017D, "STATUS_NO_LOG_SPACE" },
1634
  { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
1635
  { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
1636
  { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
1637
  { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
1638
  { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
1639
  { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
1640
  { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
1641
  { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
1642
  { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
1643
  { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
1644
  { 0xC0000188, "STATUS_LOG_FILE_FULL" },
1645
  { 0xC0000189, "STATUS_TOO_LATE" },
1646
  { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
1647
  { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
1648
  { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
1649
  { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
1650
  { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
1651
  { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
1652
  { 0xC0000190, "STATUS_TRUST_FAILURE" },
1653
  { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
1654
  { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
1655
  { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
1656
  { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
1657
  { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
1658
  { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
1659
  { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
1660
  { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
1661
  { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
1662
  { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
1663
  { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
1664
  { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
1665
  { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
1666
  { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
1667
  { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
1668
  { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
1669
  { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
1670
  { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
1671
  { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
1672
  { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
1673
  { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
1674
  { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
1675
  { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
1676
  { 0xC000020D, "STATUS_CONNECTION_RESET" },
1677
  { 0xC000020E, "STATUS_TOO_MANY_NODES" },
1678
  { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
1679
  { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
1680
  { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
1681
  { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
1682
  { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
1683
  { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
1684
  { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
1685
  { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
1686
  { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
1687
  { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
1688
  { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
1689
  { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
1690
  { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
1691
  { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
1692
  { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
1693
  { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
1694
  { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
1695
  { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
1696
  { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
1697
  { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
1698
  { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
1699
  { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
1700
  { 0xC0000225, "STATUS_NOT_FOUND" },
1701
  { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
1702
  { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
1703
  { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
1704
  { 0xC0000229, "STATUS_FAIL_CHECK" },
1705
  { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
1706
  { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
1707
  { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
1708
  { 0xC000022D, "STATUS_RETRY" },
1709
  { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
1710
  { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
1711
  { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
1712
  { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
1713
  { 0xC0000232, "STATUS_INVALID_VARIANT" },
1714
  { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
1715
  { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
1716
  { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
1717
  { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
1718
  { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
1719
  { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
1720
  { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
1721
  { 0xC000023A, "STATUS_CONNECTION_INVALID" },
1722
  { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
1723
  { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
1724
  { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
1725
  { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
1726
  { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
1727
  { 0xC0000240, "STATUS_REQUEST_ABORTED" },
1728
  { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
1729
  { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
1730
  { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
1731
  { 0xC0000244, "STATUS_AUDIT_FAILED" },
1732
  { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
1733
  { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
1734
  { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
1735
  { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
1736
  { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
1737
  { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
1738
  { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
1739
  { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
1740
  { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
1741
  { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
1742
  { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
1743
  { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
1744
  { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
1745
  { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
1746
  { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
1747
  { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
1748
  { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
1749
  { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
1750
  { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
1751
  { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
1752
  { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
1753
  { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
1754
  { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
1755
  { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
1756
  { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
1757
  { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
1758
  { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
1759
  { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
1760
  { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
1761
  { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
1762
  { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
1763
  { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
1764
  { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
1765
  { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
1766
  { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
1767
  { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
1768
  { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
1769
  { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
1770
  { 0xC0000272, "STATUS_NO_MATCH" },
1771
  { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
1772
  { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
1773
  { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
1774
  { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
1775
  { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
1776
  { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
1777
  { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
1778
  { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
1779
  { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
1780
  { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
1781
  { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
1782
  { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
1783
  { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
1784
  { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
1785
  { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
1786
  { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
1787
  { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
1788
  { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
1789
  { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
1790
  { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
1791
  { 0xC000028E, "STATUS_NO_EFS" },
1792
  { 0xC000028F, "STATUS_WRONG_EFS" },
1793
  { 0xC0000290, "STATUS_NO_USER_KEYS" },
1794
  { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
1795
  { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
1796
  { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
1797
  { 0x40000294, "STATUS_WAKE_SYSTEM" },
1798
  { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
1799
  { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
1800
  { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
1801
  { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
1802
  { 0xC0000299, "STATUS_SHARED_POLICY" },
1803
  { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
1804
  { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
1805
  { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
1806
  { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
1807
  { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
1808
  { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
1809
  { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
1810
  { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
1811
  { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
1812
  { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
1813
  { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
1814
  { 0xC00002A5, "STATUS_DS_BUSY" },
1815
  { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
1816
  { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
1817
  { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
1818
  { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
1819
  { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
1820
  { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
1821
  { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
1822
  { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
1823
  { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
1824
  { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
1825
  { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
1826
  { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
1827
  { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
1828
  { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
1829
  { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
1830
  { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
1831
  { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
1832
  { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
1833
  { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
1834
  { 0xC00002B9, "STATUS_NOINTERFACE" },
1835
  { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
1836
  { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
1837
  { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
1838
  { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
1839
  { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
1840
  { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
1841
  { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
1842
  { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
1843
  { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
1844
  { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
1845
  { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
1846
  { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
1847
  { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
1848
  { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
1849
  { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
1850
  { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
1851
  { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
1852
  { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
1853
  { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
1854
  { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
1855
  { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
1856
  { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
1857
  { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
1858
  { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
1859
  { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
1860
  { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
1861
  { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
1862
  { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
1863
  { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
1864
  { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
1865
  { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
1866
  { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
1867
  { 0xC00002E1, "STATUS_DS_CANT_START" },
1868
  { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
1869
  { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
1870
  { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
1871
  { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
1872
  { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
1873
  { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
1874
  { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
1875
  { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
1876
  { 0xC0009898, "STATUS_WOW_ASSERTION" },
1877
  { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
1878
  { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
1879
  { 0xC0020003, "RPC_NT_INVALID_BINDING" },
1880
  { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
1881
  { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
1882
  { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
1883
  { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
1884
  { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
1885
  { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
1886
  { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
1887
  { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
1888
  { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
1889
  { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
1890
  { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
1891
  { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
1892
  { 0xC0020010, "RPC_NT_NOT_LISTENING" },
1893
  { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
1894
  { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
1895
  { 0xC0020013, "RPC_NT_NO_BINDINGS" },
1896
  { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
1897
  { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
1898
  { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
1899
  { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
1900
  { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
1901
  { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
1902
  { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
1903
  { 0xC002001B, "RPC_NT_CALL_FAILED" },
1904
  { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
1905
  { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
1906
  { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
1907
  { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
1908
  { 0xC0020022, "RPC_NT_INVALID_TAG" },
1909
  { 0xC0020023, "RPC_NT_INVALID_BOUND" },
1910
  { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
1911
  { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
1912
  { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
1913
  { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
1914
  { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
1915
  { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
1916
  { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
1917
  { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
1918
  { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
1919
  { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
1920
  { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
1921
  { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
1922
  { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
1923
  { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
1924
  { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
1925
  { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
1926
  { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
1927
  { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
1928
  { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
1929
  { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
1930
  { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
1931
  { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
1932
  { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
1933
  { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
1934
  { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
1935
  { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
1936
  { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
1937
  { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
1938
  { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
1939
  { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
1940
  { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
1941
  { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
1942
  { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
1943
  { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
1944
  { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
1945
  { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
1946
  { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
1947
  { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
1948
  { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
1949
  { 0xC002100A, "RPC_P_SEND_FAILED" },
1950
  { 0xC002100B, "RPC_P_TIMEOUT" },
1951
  { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
1952
  { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
1953
  { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
1954
  { 0xC0021015, "RPC_P_THREAD_LISTENING" },
1955
  { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
1956
  { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
1957
  { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
1958
  { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
1959
  { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
1960
  { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
1961
  { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
1962
  { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
1963
  { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
1964
  { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
1965
  { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
1966
  { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
1967
  { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
1968
  { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
1969
  { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
1970
  { 0xC002004C, "EPT_NT_CANT_CREATE" },
1971
  { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
1972
  { 0xC002004F, "RPC_NT_NO_INTERFACES" },
1973
  { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
1974
  { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
1975
  { 0xC0020052, "RPC_NT_COMM_FAILURE" },
1976
  { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
1977
  { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
1978
  { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
1979
  { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
1980
  { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
1981
  { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
1982
  { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
1983
  { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
1984
  { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
1985
  { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
1986
  { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
1987
  { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
1988
  { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
1989
  { 0,          NULL }
1990
};
1991
1992
#endif /* __VALUE_STRING_H__ */
1993
1994
#endif /* _NTSTATUS_ */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/os_calls.c (-315 / +1572 lines)
 Lines 1-5    Link Here 
1
/*
1
/*
2
   Copyright (c) 2004-2010 Jay Sorg
2
   Copyright (c) 2004-2009 Jay Sorg
3
3
4
   Permission is hereby granted, free of charge, to any person obtaining a
4
   Permission is hereby granted, free of charge, to any person obtaining a
5
   copy of this software and associated documentation files (the "Software"),
5
   copy of this software and associated documentation files (the "Software"),
 Lines 35-51    Link Here 
35
#if defined(sun) || defined(__sun)
35
#if defined(sun) || defined(__sun)
36
#define ctid_t id_t
36
#define ctid_t id_t
37
#endif
37
#endif
38
#include <stddef.h>
38
#include <unistd.h>
39
#include <unistd.h>
39
#include <errno.h>
40
#include <errno.h>
41
#include <dirent.h>
42
#include <math.h>
40
#include <netinet/in.h>
43
#include <netinet/in.h>
41
#include <netinet/tcp.h>
44
#include <netinet/tcp.h>
42
#include <sys/socket.h>
43
#include <sys/un.h>
45
#include <sys/un.h>
46
#include <sys/socket.h>
44
#include <sys/time.h>
47
#include <sys/time.h>
45
#include <sys/times.h>
48
#include <sys/times.h>
46
#include <sys/types.h>
49
#include <sys/types.h>
47
#include <sys/wait.h>
50
#include <sys/wait.h>
48
#include <sys/stat.h>
51
#include <sys/stat.h>
52
#include <sys/mman.h>
49
#include <dlfcn.h>
53
#include <dlfcn.h>
50
#include <arpa/inet.h>
54
#include <arpa/inet.h>
51
#include <netdb.h>
55
#include <netdb.h>
 Lines 56-74    Link Here 
56
#include <grp.h>
60
#include <grp.h>
57
#endif
61
#endif
58
62
63
#if defined(__linux__)
64
65
#include <sys/un.h>
66
#include <sys/poll.h>
67
#include <sys/syscall.h>
68
#include <sys/types.h>
69
#include <arpa/inet.h>
70
#include <linux/serial.h>
71
#include <linux/netlink.h>
72
#include <linux/rtnetlink.h>
73
#include <linux/connector.h>
74
75
#endif
76
77
78
#include <pthread.h>
59
#include <stdlib.h>
79
#include <stdlib.h>
60
#include <string.h>
80
#include <string.h>
61
#include <stdarg.h>
81
#include <stdarg.h>
62
#include <stdio.h>
82
#include <stdio.h>
63
#include <locale.h>
83
#include <locale.h>
84
/* #include <iconv.h> */
85
#include "/usr/include/iconv.h"
64
86
65
#include "os_calls.h"
87
#include "os_calls.h"
66
#include "arch.h"
88
#include "arch.h"
89
#include "stringlist.h"
90
#include "dbg.h"
67
91
68
/* for clearenv() */
92
/* for clearenv() */
69
#if defined(_WIN32)
93
#if defined(_WIN32)
70
#else
94
#else
71
extern char** environ;
95
extern char ** environ;
72
#endif
96
#endif
73
97
74
/* for solaris */
98
/* for solaris */
 Lines 79-84    Link Here 
79
#define INADDR_NONE ((unsigned long)-1)
103
#define INADDR_NONE ((unsigned long)-1)
80
#endif
104
#endif
81
105
106
static iconv_t g_icd = (iconv_t)(-1);
107
static iconv_t g_ocd = (iconv_t)(-1);
108
static pthread_mutex_t g_mutex_iconv;
109
82
/*****************************************************************************/
110
/*****************************************************************************/
83
void APP_CC
111
void APP_CC
84
g_init(void)
112
g_init(void)
 Lines 106-125    Link Here 
106
void* APP_CC
134
void* APP_CC
107
g_malloc(int size, int zero)
135
g_malloc(int size, int zero)
108
{
136
{
109
  char* rv;
137
  void * rv = (void *)NULL;
110
138
  if (size > 0) {
111
  rv = (char*)malloc(size);
139
    rv = (zero > 0) ? (void *)calloc(size,1) : (void *)malloc(size);
112
  if (zero)
113
  {
114
    if (rv != 0)
115
    {
116
      memset(rv, 0, size);
117
    }
118
  }
140
  }
119
  return rv;
141
  return rv;
120
}
142
}
121
143
122
/*****************************************************************************/
144
/*****************************************************************************/
145
void * APP_CC
146
g_realloc(void * ptr, int size) {
147
  return (ptr == NULL || size < 1) ? (void *)NULL : (void *)realloc(ptr, size);
148
}
149
150
/*****************************************************************************/
123
/* free the memory pointed to by ptr, ptr can be zero */
151
/* free the memory pointed to by ptr, ptr can be zero */
124
void APP_CC
152
void APP_CC
125
g_free(void* ptr)
153
g_free(void* ptr)
 Lines 134-140    Link Here 
134
/* output text to stdout, try to use g_write / g_writeln instead to avoid
162
/* output text to stdout, try to use g_write / g_writeln instead to avoid
135
   linux / windows EOL problems */
163
   linux / windows EOL problems */
136
void DEFAULT_CC
164
void DEFAULT_CC
137
g_printf(const char* format, ...)
165
g_printf(const char * format, ...)
138
{
166
{
139
  va_list ap;
167
  va_list ap;
140
168
 Lines 145-151    Link Here 
145
173
146
/*****************************************************************************/
174
/*****************************************************************************/
147
void DEFAULT_CC
175
void DEFAULT_CC
148
g_sprintf(char* dest, const char* format, ...)
176
g_sprintf(char * dest, const char * format, ...)
149
{
177
{
150
  va_list ap;
178
  va_list ap;
151
179
 Lines 156-162    Link Here 
156
184
157
/*****************************************************************************/
185
/*****************************************************************************/
158
void DEFAULT_CC
186
void DEFAULT_CC
159
g_snprintf(char* dest, int len, const char* format, ...)
187
g_snprintf(char * dest, size_t len, const char * format, ...)
160
{
188
{
161
  va_list ap;
189
  va_list ap;
162
190
 Lines 166-173    Link Here 
166
}
194
}
167
195
168
/*****************************************************************************/
196
/*****************************************************************************/
197
int DEFAULT_CC
198
g_scnprintf(char * buf, size_t size, const char *fmt, ...) {
199
	va_list args;
200
	int rv = 0;
201
202
	rv = vsnprintf(buf,size,fmt,args);
203
	return (rv >= size) ? (size - 1) : rv;
204
}
205
206
/*****************************************************************************/
169
void DEFAULT_CC
207
void DEFAULT_CC
170
g_writeln(const char* format, ...)
208
g_writeln(const char * format, ...)
171
{
209
{
172
  va_list ap;
210
  va_list ap;
173
211
 Lines 183-189    Link Here 
183
221
184
/*****************************************************************************/
222
/*****************************************************************************/
185
void DEFAULT_CC
223
void DEFAULT_CC
186
g_write(const char* format, ...)
224
g_write(const char * format, ...)
187
{
225
{
188
  va_list ap;
226
  va_list ap;
189
227
 Lines 193-208    Link Here 
193
}
231
}
194
232
195
/*****************************************************************************/
233
/*****************************************************************************/
234
void DEFAULT_CC
235
g_lfile_writeln(FILE *trg, const char * format, ...)
236
{
237
  va_list ap;
238
239
  va_start(ap, format);
240
  vfprintf(trg, format, ap);
241
  va_end(ap);
242
#if defined(_WIN32)
243
  fprintf(trg, "\r\n");
244
#else
245
  fprintf(trg, "\n");
246
#endif
247
}
248
249
/*****************************************************************************/
250
void DEFAULT_CC
251
g_lfile_write(FILE *trg, const char * format, ...)
252
{
253
  va_list ap;
254
255
  va_start(ap, format);
256
  vfprintf(trg, format, ap);
257
  va_end(ap);
258
}
259
260
/*****************************************************************************/
261
void DEFAULT_CC
262
g_writeln_err(const char * format, ...)
263
{
264
  va_list ap;
265
266
  va_start(ap, format);
267
  vfprintf(stderr, format, ap);
268
  va_end(ap);
269
#if defined(_WIN32)
270
  g_printf("\r\n");
271
#else
272
  g_printf("\n");
273
#endif
274
}
275
276
/*****************************************************************************/
277
void DEFAULT_CC
278
g_write_err(const char * format, ...)
279
{
280
  va_list ap;
281
282
  va_start(ap, format);
283
  vfprintf(stderr, format, ap);
284
  va_end(ap);
285
}
286
287
/*****************************************************************************/
196
/* produce a hex dump */
288
/* produce a hex dump */
197
void APP_CC
289
void APP_CC
198
g_hexdump(char* p, int len)
290
g_hexdump(const char * p, size_t len)
199
{
291
{
200
  unsigned char* line;
292
  unsigned char * line = (unsigned char *)NULL;
201
  int i;
293
  ptrdiff_t i = 0;
202
  int thisline;
294
  int thisline = 0;
203
  int offset;
295
  ptrdiff_t offset = 0;
204
296
205
  line = (unsigned char*)p;
297
  line = (unsigned char *)p;
206
  offset = 0;
298
  offset = 0;
207
  while (offset < len)
299
  while (offset < len)
208
  {
300
  {
 Lines 231-245    Link Here 
231
}
323
}
232
324
233
/*****************************************************************************/
325
/*****************************************************************************/
326
/* produce a hex dump */
327
void APP_CC
328
g_fhexdump(char * f, char * p, size_t len)
329
{
330
  unsigned char * line = (unsigned char *)NULL;
331
  ptrdiff_t i = 0;
332
  int thisline = 0;
333
  ptrdiff_t offset = 0;
334
  FILE *fp = (FILE *)NULL;
335
336
  if (f==NULL) {
337
    f = g_malloc(sizeof(char), (strlen("/tmp/hexdump") + 1));
338
    strcpy(f,"/tmp/hexdump");
339
  }
340
341
  fp = fopen(f,"a");
342
343
  line = (unsigned char *)p;
344
  offset = 0;
345
  while (offset < len)
346
  {
347
    fprintf(fp, "%04x ", offset);
348
    thisline = len - offset;
349
    if (thisline > 16)
350
    {
351
      thisline = 16;
352
    }
353
    for (i = 0; i < thisline; i++)
354
    {
355
      fprintf(fp,"%02x ", line[i]);
356
    }
357
    for (; i < 16; i++)
358
    {
359
      fprintf(fp,"   ");
360
    }
361
    for (i = 0; i < thisline; i++)
362
    {
363
      fprintf(fp,"%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
364
    }
365
    /* g_writeln("");	*/
366
    fprintf(fp, "\n\n**********\n");
367
    offset += thisline;
368
    line += thisline;
369
  }
370
371
  fclose(fp);
372
}
373
374
/*****************************************************************************/
234
void APP_CC
375
void APP_CC
235
g_memset(void* ptr, int val, int size)
376
g_memset(void* ptr, int val, size_t size)
236
{
377
{
237
  memset(ptr, val, size);
378
  memset(ptr, val, size);
238
}
379
}
239
380
240
/*****************************************************************************/
381
/*****************************************************************************/
241
void APP_CC
382
void APP_CC
242
g_memcpy(void* d_ptr, const void* s_ptr, int size)
383
g_memcpy(void* d_ptr, const void* s_ptr, size_t size)
243
{
384
{
244
  memcpy(d_ptr, s_ptr, size);
385
  memcpy(d_ptr, s_ptr, size);
245
}
386
}
 Lines 253-278    Link Here 
253
394
254
/*****************************************************************************/
395
/*****************************************************************************/
255
int APP_CC
396
int APP_CC
256
g_tcp_set_no_delay(int sck)
397
g_tcp_set_no_delay(tbus sck)
257
{
398
{
399
  int option_value = 0;
258
#if defined(_WIN32)
400
#if defined(_WIN32)
259
  int option_value;
401
  int option_len = 0;
260
  int option_len;
261
#else
402
#else
262
  int option_value;
403
  unsigned int option_len = 0;
263
  unsigned int option_len;
264
#endif
404
#endif
265
405
266
  option_len = sizeof(option_value);
406
  option_len = sizeof(option_value);
267
  /* SOL_TCP IPPROTO_TCP */
407
  /* SOL_TCP IPPROTO_TCP */
268
  if (getsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value,
408
  if (getsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char *)&option_value,
269
                 &option_len) == 0)
409
                 &option_len) == 0)
270
  {
410
  {
271
    if (option_value == 0)
411
    if (option_value == 0)
272
    {
412
    {
273
      option_value = 1;
413
      option_value = 1;
274
      option_len = sizeof(option_value);
414
      option_len = sizeof(option_value);
275
      setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value,
415
      setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char *)&option_value,
276
                 option_len);
416
                 option_len);
277
    }
417
    }
278
  }
418
  }
 Lines 284-329    Link Here 
284
int APP_CC
424
int APP_CC
285
g_tcp_socket(void)
425
g_tcp_socket(void)
286
{
426
{
427
  int rv = 0;
428
  int option_value = 0;
429
  /* in win32 a socket is an unsigned int, in linux, its an int */
287
#if defined(_WIN32)
430
#if defined(_WIN32)
288
  int rv;
431
  int option_len = 0;
289
  int option_value;
290
  int option_len;
291
#else
432
#else
292
  int rv;
433
  unsigned int option_len = 0;
293
  int option_value;
294
  unsigned int option_len;
295
#endif
434
#endif
296
435
297
  /* in win32 a socket is an unsigned int, in linux, its an int */
436
#ifdef _XRDP_ENABLE_IPv6_
298
  rv = (int)socket(PF_INET, SOCK_STREAM, 0);
437
  rv = (int)socket(AF_INET6, SOCK_STREAM, 0);
438
#else
439
  rv = (int)socket(AF_INET, SOCK_STREAM, 0);
440
#endif
299
  if (rv < 0)
441
  if (rv < 0)
300
  {
442
  {
301
    return -1;
443
    rv = -1;
302
  }
444
  }
303
  option_len = sizeof(option_value);
445
  else {
304
  if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char*)&option_value,
446
#ifdef _XRDP_ENABLE_IPv6_
305
                 &option_len) == 0)
447
    option_len = sizeof(option_value);
306
  {
448
    if (getsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&option_value,
307
    if (option_value == 0)
449
                   &option_len) == 0)
308
    {
450
    {
309
      option_value = 1;
451
      if (option_value != 0)
310
      option_len = sizeof(option_value);
452
      {
311
      setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char*)&option_value,
453
        option_value = 0;
312
                 option_len);
454
        option_len = sizeof(option_value);
455
        setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&option_value,
456
                   option_len);
457
      }
313
    }
458
    }
314
  }
459
#endif
315
  option_len = sizeof(option_value);
460
    option_len = sizeof(option_value);
316
  if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char*)&option_value,
461
    if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
317
                 &option_len) == 0)
462
                   &option_len) == 0)
318
  {
319
    if (option_value < (1024 * 32))
320
    {
463
    {
321
      option_value = 1024 * 32;
464
      if (option_value == 0)
322
      option_len = sizeof(option_value);
465
      {
323
      setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char*)&option_value,
466
        option_value = 1;
324
                 option_len);
467
        option_len = sizeof(option_value);
468
        setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
469
                   option_len);
470
      }
471
    }
472
    option_len = sizeof(option_value);
473
    if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
474
                   &option_len) == 0)
475
    {
476
      if (option_value < (1024 * 32))
477
      {
478
        option_value = 1024 * 32;
479
        option_len = sizeof(option_value);
480
        setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
481
                   option_len);
482
      }
325
    }
483
    }
326
  }
484
  }
485
  MDBGLOG("chansrv","INFO\t[%s()]: done (rv = %d).",__func__,rv);
327
  return rv;
486
  return rv;
328
}
487
}
329
488
 Lines 331-336    Link Here 
331
int APP_CC
490
int APP_CC
332
g_tcp_local_socket(void)
491
g_tcp_local_socket(void)
333
{
492
{
493
  MDBGLOG("net","INFO\t[%s()]: called",__func__);
334
#if defined(_WIN32)
494
#if defined(_WIN32)
335
  return 0;
495
  return 0;
336
#else
496
#else
 Lines 339-415    Link Here 
339
}
499
}
340
500
341
/*****************************************************************************/
501
/*****************************************************************************/
342
void APP_CC
502
int APP_CC
343
g_tcp_close(int sck)
503
g_socketpair(int * fds)
344
{
504
{
345
  if (sck == 0)
505
  MDBGLOG("net","INFO\t[%s()]: called",__func__);
506
#if defined(_WIN32)
507
  return 0;
508
#else
509
  return socketpair(PF_LOCAL, SOCK_STREAM, 0, fds);
510
#endif
511
}
512
513
/*****************************************************************************/
514
void APP_CC
515
g_tcp_close(tbus sck) {
516
  MDBGLOG("net","INFO\t[%s()]: called (sck = %d)",__func__,sck);
517
  if (sck != 0)
346
  {
518
  {
347
    return;
519
    shutdown(sck, 2);
348
  }
349
  shutdown(sck, 2);
350
#if defined(_WIN32)
520
#if defined(_WIN32)
351
  closesocket(sck);
521
    closesocket(sck);
352
#else
522
#else
353
  close(sck);
523
    close(sck);
354
#endif
524
#endif
525
  }
526
  MDBGLOG("net","INFO\t[%s()]: done.",__func__);
355
}
527
}
356
528
357
/*****************************************************************************/
529
/*****************************************************************************/
358
/* returns error, zero is good */
530
/* returns error, zero is good */
359
int APP_CC
531
int APP_CC
360
g_tcp_connect(int sck, const char* address, const char* port)
532
g_tcp_connect(tbus sck, const char * address, const char * port)
361
{
533
{
362
  struct sockaddr_in s;
534
  int res = 0;
363
  struct hostent* h;
535
  struct addrinfo p;
364
536
  struct addrinfo *h = (struct addrinfo *)NULL;
365
  g_memset(&s, 0, sizeof(struct sockaddr_in));
537
  struct addrinfo *rp = (struct addrinfo *)NULL;
366
  s.sin_family = AF_INET;
538
367
  s.sin_port = htons((tui16)atoi(port));
539
  /* initialize (zero out) local variables: */
368
  s.sin_addr.s_addr = inet_addr(address);
540
  g_memset(&p,0,sizeof(struct addrinfo));
369
  if (s.sin_addr.s_addr == INADDR_NONE)
541
370
  {
542
  /* in IPv6-enabled environments, set the AI_V4MAPPED
371
    h = gethostbyname(address);
543
   * flag in ai_flags and specify ai_family=AF_INET6 in
372
    if (h != 0)
544
   * order to ensure that getaddrinfo() returns any
373
    {
545
   * available IPv4-mapped addresses in case the target
374
      if (h->h_name != 0)
546
   * host does not have a true IPv6 address:
375
      {
547
   */
376
        if (h->h_addr_list != 0)
548
#ifdef _XRDP_ENABLE_IPv6_
377
        {
549
  p.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
378
          if ((*(h->h_addr_list)) != 0)
550
  p.ai_family = AF_INET6;
379
          {
551
#else
380
            s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
552
  p.ai_flags = AI_ADDRCONFIG;
381
          }
553
  p.ai_family = AF_INET;
382
        }
554
#endif
555
  p.ai_socktype = SOCK_STREAM;
556
  p.ai_protocol = IPPROTO_TCP;
557
  res = getaddrinfo(address,port,&p,&h);
558
  if (res > -1) {
559
    if (h != NULL) {
560
      for (rp = h; rp != NULL; rp = rp->ai_next) {
561
	rp = h;
562
	res = connect(sck, (struct sockaddr *)(rp->ai_addr), rp->ai_addrlen);
563
	if (res != -1) {
564
	  break;                  /* Success */
565
	}
383
      }
566
      }
384
    }
567
    }
385
  }
568
  }
386
  return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
569
  return res;
387
}
570
}
388
571
389
/*****************************************************************************/
572
/*****************************************************************************/
390
/* returns error, zero is good */
573
/* returns error, zero is good */
391
int APP_CC
574
int APP_CC
392
g_tcp_local_connect(int sck, const char* port)
575
g_tcp_local_connect(tbus sck, const char * port)
393
{
576
{
577
  MDBGLOG("net","INFO\t[%s()]: called (port = \"%s\")",__func__,((port == NULL || g_strlen(port) < 1)?"(none)":port));
394
#if defined(_WIN32)
578
#if defined(_WIN32)
395
  return -1;
579
  return -1;
396
#else
580
#else
397
  struct sockaddr_un s;
581
  size_t len = 0;
582
  struct sockaddr_un * s = (struct sockaddr_un *)NULL;
398
583
399
  memset(&s, 0, sizeof(struct sockaddr_un));
584
  s = (struct sockaddr_un *)g_malloc(sizeof(struct sockaddr_un), 1);
400
  s.sun_family = AF_UNIX;
585
  if (s != NULL) {
401
  strcpy(s.sun_path, port);
586
    s->sun_family = AF_UNIX;
402
  return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_un));
587
    g_strncpy(s->sun_path, port, 104);
588
    len = sizeof(s->sun_family) + g_strlen(s->sun_path);
589
    MDBGLOG("net","INFO\t[%s()]: done.",__func__);
590
    return connect(sck, (const struct sockaddr *)s, len);
591
  }
592
  else {
593
    MDBGLOG("net","ERROR\t[%s()]: out of memory",__func__);
594
    return -ENOMEM;
595
  }
403
#endif
596
#endif
404
}
597
}
405
598
406
/*****************************************************************************/
599
/*****************************************************************************/
407
int APP_CC
600
int APP_CC
408
g_tcp_set_non_blocking(int sck)
601
g_tcp_set_non_blocking(tbus sck)
409
{
602
{
410
  unsigned long i;
603
  unsigned long i = 0;
411
604
412
#if defined(_WIN32)
605
  MDBGLOG("net","INFO\t[%s()]: called (sck = %d)",__func__,sck);
606
#ifdef _WIN32
413
  i = 1;
607
  i = 1;
414
  ioctlsocket(sck, FIONBIO, &i);
608
  ioctlsocket(sck, FIONBIO, &i);
415
#else
609
#else
 Lines 417-581    Link Here 
417
  i = i | O_NONBLOCK;
611
  i = i | O_NONBLOCK;
418
  fcntl(sck, F_SETFL, i);
612
  fcntl(sck, F_SETFL, i);
419
#endif
613
#endif
614
  MDBGLOG("net","INFO\t[%s()]: done.",__func__);
420
  return 0;
615
  return 0;
421
}
616
}
422
617
423
/*****************************************************************************/
618
/*****************************************************************************/
424
/* returns error, zero is good */
425
int APP_CC
619
int APP_CC
426
g_tcp_bind(int sck, char* port)
620
g_tcp_set_blocking(tbus sck)
427
{
621
{
428
  struct sockaddr_in s;
622
  unsigned long i = 0;
623
624
  MDBGLOG("net","INFO\t[%s()]: called (sck = %d)",__func__,sck);
625
#ifdef _WIN32
626
  i = 1;
627
  ioctlsocket(sck, FIONBIO, &i);
628
#else
629
  i = fcntl(sck, F_GETFL);
630
  i &= ~O_NONBLOCK;
631
  fcntl(sck, F_SETFL, i);
632
#endif
633
  MDBGLOG("net","INFO\t[%s()]: done.",__func__);
634
  return 0;
635
}
429
636
430
  memset(&s, 0, sizeof(struct sockaddr_in));
637
/*****************************************************************************/
431
  s.sin_family = AF_INET;
638
int APP_CC
432
  s.sin_port = htons((tui16)atoi(port));
639
g_fifo_set_blocking(tbus fd) {
433
  s.sin_addr.s_addr = INADDR_ANY;
640
  int rv = 0;
434
  return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
641
#ifdef _WIN32
642
  rv = -EINVAL;
643
#else
644
  uint32_t i = 0;
645
  const uint32_t nb = O_NONBLOCK;
646
647
  MDBGLOG("net","INFO\t[%s()]: called (fd = %d)",__func__,fd);
648
649
  if (fd < 1) {
650
    rv = -EINVAL;
651
  }
652
  else {
653
    i = fcntl(fd, F_GETFL);
654
    if ((i & nb) > 0) {
655
      i = i ^ nb;
656
    }
657
    fcntl(fd, F_SETFL, i);
658
  }
659
#endif
660
  MDBGLOG("net","INFO\t[%s()]: done (rv = %d).",__func__,rv);
661
  return rv;
435
}
662
}
436
663
664
437
/*****************************************************************************/
665
/*****************************************************************************/
666
/* returns error, zero is good */
438
int APP_CC
667
int APP_CC
439
g_tcp_local_bind(int sck, char* port)
668
g_tcp_bind_flags(tbus sck, const char * port, int flags) {
440
{
669
  int res = -1;
441
#if defined(_WIN32)
670
  int error = 0;
442
  return -1;
671
#ifdef _XRDP_ENABLE_IPv6_
672
  int ipv4 = 0;
673
#endif
674
  struct addrinfo hints;
675
  struct addrinfo * i = (struct addrinfo *)NULL;
676
  struct addrinfo * j = (struct addrinfo *)NULL;
677
678
  /* initialize (zero out) local variables: */
679
  g_memset(&hints, 0, sizeof(hints));
680
681
  hints.ai_family = AF_UNSPEC;
682
  hints.ai_flags = flags;
683
  hints.ai_socktype = SOCK_STREAM;
684
  hints.ai_protocol = IPPROTO_TCP;
685
  error = getaddrinfo(NULL,port,&hints,&i);
686
  if (error) {
687
    res = -1;
688
  }
689
  else {
690
    /* iterate the entire list returned by getaddrinfo()
691
     * and determine how many IPv6 and IPv4 addresses, respectively,
692
     * are available:
693
     */
694
    j = i;
695
#ifdef _XRDP_ENABLE_IPv6_
696
    while (j && (res < 0)) {
697
      if (j->ai_family == PF_INET6) {
698
	res = bind(sck, (struct sockaddr *)j->ai_addr, j->ai_addrlen);
699
      }
700
      else {
701
	ipv4++;
702
      }
703
      j = j->ai_next;
704
    }
705
    if ((res < 0) && (ipv4 > 0)) {
706
      j = i;
707
      while (j && (res < 0)) {
708
	if (j->ai_family != PF_INET6) {
709
	  res = bind(sck, (struct sockaddr *)j->ai_addr, j->ai_addrlen);
710
	}
711
	j = j->ai_next;
712
      }
713
    }
443
#else
714
#else
444
  struct sockaddr_un s;
715
    while (j && (res < 0)) {
716
      res = bind(sck, (struct sockaddr *)j->ai_addr, j->ai_addrlen);
717
      j = j->ai_next;
718
    }
719
#endif
720
  }
721
722
  return res;
723
}
724
725
726
/*****************************************************************************/
727
/* returns error, zero is good */
728
int APP_CC
729
g_tcp_bind(tbus sck, const char * port) {
730
  const int flags = AI_ADDRCONFIG;
731
  return g_tcp_bind_flags(sck, port, flags);
732
}
733
445
734
446
  memset(&s, 0, sizeof(struct sockaddr_un));
735
/*****************************************************************************/
447
  s.sun_family = AF_UNIX;
736
int APP_CC
448
  strcpy(s.sun_path, port);
737
g_tcp_local_bind(tbus sck, const char * port) {
449
  return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_un));
738
  int rv = 0;
739
#if defined(_WIN32)
740
  rv = -EINVAL;
741
#else
742
  if (sck < 1 || port == NULL || g_strlen(port) < 1) {
743
    rv = -EINVAL;
744
  }
745
  else {
746
    size_t len = 0;
747
    struct sockaddr_un ls;
748
    struct sockaddr_un * s = &ls;
749
    g_memset(s,0,sizeof(struct sockaddr_un));
750
    s->sun_family = AF_UNIX;
751
    g_strncpy(s->sun_path, port, sizeof(s->sun_path));
752
    len = sizeof(struct sockaddr_un);
753
    rv = bind(sck, (const struct sockaddr *)s, len);
754
  }
450
#endif
755
#endif
756
  return rv;
451
}
757
}
452
758
453
/*****************************************************************************/
759
/*****************************************************************************/
454
/* returns error, zero is good */
760
/* returns error, zero is good */
455
int APP_CC
761
int APP_CC
456
g_tcp_listen(int sck)
762
g_tcp_listen(tbus sck)
457
{
763
{
458
  return listen(sck, 2);
764
  return listen(sck, 2);
459
}
765
}
460
766
461
/*****************************************************************************/
767
/*****************************************************************************/
462
int APP_CC
768
int APP_CC
463
g_tcp_accept(int sck)
769
g_tcp_accept(tbus sck)
464
{
770
{
465
  struct sockaddr_in s;
771
  struct sockaddr_storage s;
466
#if defined(_WIN32)
772
#if defined(_WIN32)
467
  signed int i;
773
  signed int i = 0;
468
#else
774
#else
469
  unsigned int i;
775
  unsigned int i = 0;
470
#endif
776
#endif
471
777
  i = sizeof(struct sockaddr_storage);
472
  i = sizeof(struct sockaddr_in);
778
  g_memset(&s,0,i);
473
  memset(&s, 0, i);
474
  return accept(sck, (struct sockaddr*)&s, &i);
779
  return accept(sck, (struct sockaddr*)&s, &i);
475
}
780
}
476
781
477
/*****************************************************************************/
782
/*****************************************************************************/
478
void APP_CC
783
void APP_CC
479
g_sleep(int msecs)
784
g_sleep(uint64_t msecs)
480
{
785
{
481
#if defined(_WIN32)
786
#if defined(_WIN32)
482
  Sleep(msecs);
787
  Sleep(msecs);
483
#else
788
#else
484
  usleep(msecs * 1000);
789
  useconds_t us = 0;
790
  us += msecs;
791
  us *= 1000;
792
  usleep(us);
793
#endif
794
}
795
796
/*****************************************************************************/
797
void APP_CC
798
g_usleep(uint64_t usecs)
799
{
800
#if defined(_WIN32)
801
#else
802
  usleep(usecs);
485
#endif
803
#endif
486
}
804
}
487
805
488
/*****************************************************************************/
806
/*****************************************************************************/
489
int APP_CC
807
int APP_CC
490
g_tcp_last_error_would_block(int sck)
808
g_tcp_last_error_would_block(tbus sck)
491
{
809
{
492
#if defined(_WIN32)
810
#if defined(_WIN32)
493
  return WSAGetLastError() == WSAEWOULDBLOCK;
811
  return WSAGetLastError() == WSAEWOULDBLOCK;
494
#else
812
#else
495
  return (errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINPROGRESS);
813
  return (errno == EWOULDBLOCK) || (errno == EINPROGRESS);
496
#endif
814
#endif
497
}
815
}
498
816
499
/*****************************************************************************/
817
/*****************************************************************************/
500
int APP_CC
818
size_t APP_CC
501
g_tcp_recv(int sck, void* ptr, int len, int flags)
819
g_tcp_recv(tbus sck, void * ptr, size_t len, int flags)
502
{
820
{
503
#if defined(_WIN32)
821
#if defined(_WIN32)
504
  return recv(sck, (char*)ptr, len, flags);
822
  return recv(sck, (char *)ptr, len, flags);
823
#else
824
  size_t rv = 0;
825
826
  if (sck == 0 || ptr == NULL || len < 0) {
827
    rv = 0;
828
  }
829
  else if (len == 0) {
830
    rv = 0;
831
  }
832
  else {
833
    rv = recv(sck, ptr, len, flags);
834
  }
835
  return rv;
836
837
#endif
838
}
839
840
/*****************************************************************************/
841
size_t APP_CC
842
g_fifo_read(tbus fd, void * ptr, size_t len)
843
{
844
  size_t rv = 0;
845
846
  if (fd == 0 || ptr == NULL || len < 0) {
847
    rv = 0;
848
  }
849
  else if (len == 0) {
850
    rv = 0;
851
  }
852
  else {
853
    rv = read(fd, ptr, len);
854
  }
855
  return rv;
856
}
857
858
/*****************************************************************************/
859
size_t APP_CC
860
g_fifo_write(tbus fd, const void * ptr, size_t len)
861
{
862
  size_t rv = 0;
863
864
  if (fd == 0 || ptr == NULL || len < 0) {
865
    rv = 0;
866
  }
867
  else if (len == 0) {
868
    rv = 0;
869
  }
870
  else {
871
#ifdef _WIN32
872
    rv = write(fd, (const char *)ptr, len);
505
#else
873
#else
506
  return recv(sck, ptr, len, flags);
874
    rv = write(fd, ptr, len);
507
#endif
875
#endif
876
  }
877
  return rv;
508
}
878
}
509
879
510
/*****************************************************************************/
880
/*****************************************************************************/
511
int APP_CC
881
size_t APP_CC
512
g_tcp_send(int sck, const void* ptr, int len, int flags)
882
g_tcp_send(tbus sck, const void* ptr, size_t len, int flags)
513
{
883
{
884
  if (sck > -1 && ptr != NULL && len > 0 && g_tcp_socket_ok(sck)) {
514
#if defined(_WIN32)
885
#if defined(_WIN32)
515
  return send(sck, (const char*)ptr, len, flags);
886
    return (size_t)(send(sck, (const char *)ptr, len, flags));
516
#else
887
#else
517
  return send(sck, ptr, len, flags);
888
    return (size_t)(send(sck, ptr, len, flags));
518
#endif
889
#endif
890
  }
891
  else {
892
    return 0;
893
  }
894
}
895
896
/*****************************************************************************/
897
size_t APP_CC
898
g_tcp_send_force(tbus sck, const void * ptr, size_t len, int flags)
899
{
900
  size_t rv = 0;
901
  size_t rem = len;
902
  if (sck > -1 && ptr != NULL && len > 0) {
903
    while (rem > 0) {
904
      if (0 && !g_tcp_socket_ok(sck)) {
905
	rv = 0;
906
	break;
907
      }
908
      else if (g_tcp_can_send(sck, 300)) {
909
#if defined(_WIN32)
910
	rem -= (size_t)(send(sck, (const char *)ptr, len, flags));
911
#else
912
	rem -= (size_t)(send(sck, ptr, len, flags));
913
#endif
914
      }
915
    }
916
    rv = len;
917
  }
918
  return rv;
519
}
919
}
520
920
521
/*****************************************************************************/
921
/*****************************************************************************/
522
/* returns boolean */
922
/* returns boolean */
523
int APP_CC
923
int APP_CC
524
g_tcp_socket_ok(int sck)
924
g_tcp_socket_ok(tbus sck)
525
{
925
{
926
  int res = 0;
927
  int opt = 0;
526
#if defined(_WIN32)
928
#if defined(_WIN32)
527
  int opt;
929
  int opt_len = 0;
528
  int opt_len;
529
#else
930
#else
530
  int opt;
931
  unsigned int opt_len = 0;
531
  unsigned int opt_len;
532
#endif
932
#endif
533
933
534
  opt_len = sizeof(opt);
934
  if (sck < 0) {
535
  if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char*)(&opt), &opt_len) == 0)
935
    res = 0;
536
  {
936
  }
537
    if (opt == 0)
937
  else {
938
    opt_len = sizeof(opt);
939
    if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char *)(&opt), &opt_len) == 0)
538
    {
940
    {
539
      return 1;
941
      if (opt == 0)
942
      {
943
        res = 1;
944
      }
540
    }
945
    }
541
  }
946
  }
542
  return 0;
947
  return res;
543
}
948
}
544
949
545
/*****************************************************************************/
950
/*****************************************************************************/
546
/* wait 'millis' milliseconds for the socket to be able to write */
951
/* wait 'millis' milliseconds for the socket to be able to write */
547
/* returns boolean */
952
/* returns boolean */
548
int APP_CC
953
int APP_CC
549
g_tcp_can_send(int sck, int millis)
954
g_tcp_can_send(tbus sck, int millis) {
550
{
551
  fd_set wfds;
955
  fd_set wfds;
552
  struct timeval time;
956
  struct timeval time;
553
  int rv;
957
  int rv = 0;
958
959
  if (sck < 1) {
960
    rv = 0;
961
    goto end;
962
  }
963
964
  //DBGLOG("net","[os_calls]->g_tcp_can_send() called");
965
  g_memset(&wfds,0,sizeof(fd_set));
966
  g_memset(&time,0,sizeof(struct timeval));
554
967
555
  time.tv_sec = millis / 1000;
968
  time.tv_sec = millis / 1000;
556
  time.tv_usec = (millis * 1000) % 1000000;
969
  time.tv_usec = (millis * 1000) % 1000000;
557
  FD_ZERO(&wfds);
970
  FD_ZERO(&wfds);
558
  if (sck > 0)
971
  if (sck > 0) {
559
  {
560
    FD_SET(((unsigned int)sck), &wfds);
972
    FD_SET(((unsigned int)sck), &wfds);
561
    rv = select(sck + 1, 0, &wfds, 0, &time);
973
    rv = select(sck + 1, 0, &wfds, 0, &time);
562
    if (rv > 0)
974
    if (rv > 0)
563
    {
975
    {
564
      return g_tcp_socket_ok(sck);
976
      rv = g_tcp_socket_ok(sck);
977
    }
978
    else
979
    {
980
      rv = 0;
565
    }
981
    }
566
  }
982
  }
567
  return 0;
983
984
 end:;
985
  return rv;
568
}
986
}
569
987
570
/*****************************************************************************/
988
/*****************************************************************************/
571
/* wait 'millis' milliseconds for the socket to be able to receive */
989
/* wait 'millis' milliseconds for the socket to be able to receive */
572
/* returns boolean */
990
/* returns boolean */
573
int APP_CC
991
int APP_CC
574
g_tcp_can_recv(int sck, int millis)
992
g_tcp_can_recv(tbus sck, int millis)
575
{
993
{
576
  fd_set rfds;
994
  fd_set rfds;
577
  struct timeval time;
995
  struct timeval time;
578
  int rv;
996
  int rv = 0;
997
  int res = 0;
998
999
  g_memset(&time,0,sizeof(struct timeval));
1000
  g_memset(&rfds,0,sizeof(fd_set));
579
1001
580
  time.tv_sec = millis / 1000;
1002
  time.tv_sec = millis / 1000;
581
  time.tv_usec = (millis * 1000) % 1000000;
1003
  time.tv_usec = (millis * 1000) % 1000000;
 Lines 586-605    Link Here 
586
    rv = select(sck + 1, &rfds, 0, 0, &time);
1008
    rv = select(sck + 1, &rfds, 0, 0, &time);
587
    if (rv > 0)
1009
    if (rv > 0)
588
    {
1010
    {
589
      return g_tcp_socket_ok(sck);
1011
      res = g_tcp_socket_ok(sck);
1012
    }
1013
    else
1014
    {
1015
      res = 0;
590
    }
1016
    }
591
  }
1017
  }
592
  return 0;
1018
  return res;
593
}
1019
}
594
1020
595
/*****************************************************************************/
1021
/*****************************************************************************/
1022
/* wait 'millis' milliseconds for the FIFO to be able to receive */
1023
/* returns boolean */
596
int APP_CC
1024
int APP_CC
597
g_tcp_select(int sck1, int sck2)
1025
g_fifo_can_read(tbus fd, int millis)
598
{
1026
{
599
  fd_set rfds;
1027
  fd_set rfds;
600
  struct timeval time;
1028
  struct timeval time;
601
  int max;
1029
  int rv = 0;
602
  int rv;
1030
  int res = 0;
1031
1032
  g_memset(&time,0,sizeof(struct timeval));
1033
  g_memset(&rfds,0,sizeof(fd_set));
1034
1035
  time.tv_sec = millis / 1000;
1036
  time.tv_usec = (millis * 1000) % 1000000;
1037
  FD_ZERO(&rfds);
1038
  if (fd > -1)
1039
  {
1040
    FD_SET(((unsigned int)fd), &rfds);
1041
    rv = select(fd + 1, &rfds, 0, 0, &time);
1042
    if (rv > 0)
1043
    {
1044
      res = 1;
1045
    }
1046
    else
1047
    {
1048
      res = 0;
1049
    }
1050
  }
1051
  return res;
1052
}
1053
1054
/*****************************************************************************/
1055
int APP_CC
1056
g_tcp_select(tbus sck1, tbus sck2)
1057
{
1058
  fd_set rfds;
1059
  struct timeval time;
1060
  int max = 0;
1061
  int rv = 0;
1062
1063
  g_memset(&rfds,0,sizeof(fd_set));
1064
  g_memset(&time,0,sizeof(struct timeval));
603
1065
604
  time.tv_sec = 0;
1066
  time.tv_sec = 0;
605
  time.tv_usec = 0;
1067
  time.tv_usec = 0;
 Lines 640-688    Link Here 
640
/*****************************************************************************/
1102
/*****************************************************************************/
641
/* returns 0 on error */
1103
/* returns 0 on error */
642
tbus APP_CC
1104
tbus APP_CC
643
g_create_wait_obj(char* name)
1105
g_create_wait_obj(const char * name)
644
{
1106
{
645
#ifdef _WIN32
1107
  tbus obj = (tbus)(-1);
646
  tbus obj;
647
1108
1109
#ifdef _WIN32
648
  obj = (tbus)CreateEvent(0, 1, 0, name);
1110
  obj = (tbus)CreateEvent(0, 1, 0, name);
649
  return obj;
1111
  return obj;
650
#else
1112
#else
651
  tbus obj;
652
  struct sockaddr_un sa;
1113
  struct sockaddr_un sa;
653
  int len;
1114
  size_t len = 0;
654
  int sck;
1115
  tbus sck = -1;
655
  int i;
1116
  int i = 0;
656
1117
657
  sck = socket(PF_UNIX, SOCK_DGRAM, 0);
1118
  MDBGLOG("net","INFO\t[%s()]: called (name = %s)",__func__,name);
1119
  g_memset(&sa,0,sizeof(struct sockaddr_un));
1120
1121
  sck = socket(PF_LOCAL, SOCK_DGRAM, 0);
658
  if (sck < 0)
1122
  if (sck < 0)
659
  {
1123
  {
660
    return 0;
1124
    return 0;
661
  }
1125
  }
662
  memset(&sa, 0, sizeof(sa));
1126
  sa.sun_family = AF_LOCAL;
663
  sa.sun_family = AF_UNIX;
664
  if ((name == 0) || (strlen(name) == 0))
1127
  if ((name == 0) || (strlen(name) == 0))
665
  {
1128
  {
666
    g_random((char*)&i, sizeof(i));
1129
    g_random((char *)&i, sizeof(i));
667
    sprintf(sa.sun_path, "/tmp/auto%8.8x", i);
1130
    sprintf(sa.sun_path, "/tmp/auto%8.8x", i);
668
    while (g_file_exist(sa.sun_path))
1131
    while (g_file_exist(sa.sun_path)) {
669
    {
1132
      g_random((char *)&i, sizeof(i));
670
      g_random((char*)&i, sizeof(i));
671
      sprintf(sa.sun_path, "/tmp/auto%8.8x", i);
1133
      sprintf(sa.sun_path, "/tmp/auto%8.8x", i);
672
    }
1134
    }
673
  }
1135
  }
674
  else
1136
  else
675
  {
1137
  {
676
    sprintf(sa.sun_path, "/tmp/%s", name);
1138
    g_sprintf(sa.sun_path, "/tmp/%s", name);
1139
  }
1140
  unlink(sa.sun_path);
1141
  len = sizeof(sa);
1142
  if (bind(sck, (const struct sockaddr *)&sa, len) < 0)
1143
  {
1144
    MDBGLOG("net","ERROR\t[%s()]: bind() failed",__func__);
1145
    close(sck);
1146
    return 0;
1147
  }
1148
  obj = (tbus)sck;
1149
1150
  MDBGLOG("net","INFO\t[%s()]: done (obj = %d).",__func__,sck);
1151
  return obj;
1152
#endif
1153
}
1154
1155
/*****************************************************************************/
1156
/* returns 0 on error */
1157
tbus APP_CC
1158
g_create_wait_obj_from_path(const char * path) {
1159
  tbus obj = (tbus)(-1);
1160
1161
#ifdef _WIN32
1162
  obj = (tbus)CreateEvent(0, 1, 0, name);
1163
  return obj;
1164
#else
1165
  struct sockaddr_un sa;
1166
  size_t len = 0;
1167
  tbus sck = -1;
1168
  int i = 0;
1169
1170
  MDBGLOG("net","INFO\t[%s()]: called (path = %s)",__func__,path);
1171
  g_memset(&sa,0,sizeof(struct sockaddr_un));
1172
1173
  sck = socket(PF_LOCAL, SOCK_DGRAM, 0);
1174
  if (sck < 0)
1175
  {
1176
    return 0;
1177
  }
1178
  sa.sun_family = AF_LOCAL;
1179
  if ((path == 0) || (strlen(path) == 0))
1180
  {
1181
    g_random((char *)&i, sizeof(i));
1182
    g_snprintf(sa.sun_path, sizeof(sa.sun_path), "/tmp/auto%8.8x", i);
1183
    while (g_file_exist(sa.sun_path)) {
1184
      g_random((char *)&i, sizeof(i));
1185
      g_snprintf(sa.sun_path, sizeof(sa.sun_path), "/tmp/auto%8.8x", i);
1186
    }
1187
  }
1188
  else
1189
  {
1190
    g_snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", path);
677
  }
1191
  }
678
  unlink(sa.sun_path);
1192
  unlink(sa.sun_path);
679
  len = sizeof(sa);
1193
  len = sizeof(sa);
680
  if (bind(sck, (struct sockaddr*)&sa, len) < 0)
1194
  if (bind(sck, (const struct sockaddr *)&sa, len) < 0)
681
  {
1195
  {
1196
    MDBGLOG("net","ERROR\t[%s()]: bind() failed",__func__);
682
    close(sck);
1197
    close(sck);
683
    return 0;
1198
    return 0;
684
  }
1199
  }
685
  obj = (tbus)sck;
1200
  obj = (tbus)sck;
1201
1202
  MDBGLOG("net","INFO\t[%s()]: done (obj = %d).",__func__,sck);
686
  return obj;
1203
  return obj;
687
#endif
1204
#endif
688
}
1205
}
 Lines 695-701    Link Here 
695
#ifdef _WIN32
1212
#ifdef _WIN32
696
  /* Create and return corresponding event handle for WaitForMultipleObjets */
1213
  /* Create and return corresponding event handle for WaitForMultipleObjets */
697
  WSAEVENT event;
1214
  WSAEVENT event;
698
  long lnetevent;
1215
  long lnetevent = 0;
1216
1217
  g_memset(&event,0,sizeof(WSAEVENT));
699
1218
700
  event = WSACreateEvent();
1219
  event = WSACreateEvent();
701
  lnetevent = (write ? FD_WRITE : FD_READ) | FD_CLOSE;
1220
  lnetevent = (write ? FD_WRITE : FD_READ) | FD_CLOSE;
 Lines 708-721    Link Here 
708
    return 0;
1227
    return 0;
709
  }
1228
  }
710
#else
1229
#else
1230
  MDBGLOG("net","INFO\t[%s()]: done (socket = %d; write = %d)",__func__,(int)socket,write);
1231
711
  return socket;
1232
  return socket;
712
#endif
1233
#endif
713
}
1234
}
714
1235
715
/*****************************************************************************/
1236
/*****************************************************************************/
1237
/* returns 0 on error */
1238
tbus APP_CC
1239
g_create_wait_obj_from_fifo(tbus fifo, int write)
1240
{
1241
#ifdef _WIN32
1242
  /* Create and return corresponding event handle for WaitForMultipleObjets */
1243
  WSAEVENT event;
1244
  long lnetevent = 0;
1245
1246
  g_memset(&event,0,sizeof(WSAEVENT));
1247
1248
  event = WSACreateEvent();
1249
  lnetevent = (write ? FD_WRITE : FD_READ) | FD_CLOSE;
1250
  if (WSAEventSelect(fifo, event, lnetevent) == 0)
1251
  {
1252
    return (tbus)event;
1253
  }
1254
  else
1255
  {
1256
    return 0;
1257
  }
1258
#else
1259
  MDBGLOG("net","INFO\t[%s()]: called (fifo FD = %d; write = %d)",__func__,(int)fifo,write);
1260
1261
  return fifo;
1262
#endif
1263
}
1264
1265
/*****************************************************************************/
1266
/* returns -1 on error, else return handle or file descriptor */
1267
int APP_CC
1268
g_create_fifo(const char * file_name) {
1269
#if defined(_WIN32)
1270
  return (int)CreateFileA(file_name, GENERIC_READ,
1271
                          FILE_SHARE_READ,
1272
                          0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1273
#else
1274
  int rv = 0;
1275
  MDBGLOG("net","INFO\t[%s()]: called (file_name = %s)",__func__,file_name);
1276
  if (file_name == NULL || g_strlen(file_name) < 1) {
1277
    rv = -1;
1278
  }
1279
  else {
1280
    g_file_delete(file_name);
1281
    rv = g_mkfifo(file_name, 0666);
1282
  }
1283
  MDBGLOG("net","INFO\t[%s()]: called (rv = %d).",__func__,rv);
1284
  return rv;
1285
#endif
1286
}
1287
1288
/*****************************************************************************/
1289
/* returns -1 on error, else return handle or file descriptor */
1290
int APP_CC
1291
g_create_selfpipe(const char * file_name)
1292
{
1293
#if defined(_WIN32)
1294
  return (int)CreateFileA(file_name, GENERIC_READ,
1295
                          FILE_SHARE_READ,
1296
                          0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1297
#else
1298
  int rv = 0;
1299
1300
  MDBGLOG("net","INFO\t[%s()]: called (file_name = %s)",__func__,file_name);
1301
1302
  rv = g_mkfifo(file_name, 0666);
1303
1304
  /* The following statement works correctly under Linux,
1305
   * but its behavior is non-standard (the POSIX standard
1306
   * does not define what occurs when a FIFO is opened
1307
   * with the O_RDWR flag).
1308
   */
1309
  rv = open(file_name, O_RDWR | O_NDELAY);
1310
1311
  /* If the non-standard method does not work, then the
1312
   * following method is more POSIX-compliant; however, it
1313
   * may be susceptible to a potential race condition.
1314
   */
1315
  if (rv < 0) {
1316
    rv = open(file_name, O_RDONLY);
1317
    rv = open(file_name, O_WRONLY);
1318
  }
1319
1320
  MDBGLOG("net","INFO\t[%s()]: done (rv = %d)",__func__,rv);
1321
1322
  return rv;
1323
#endif
1324
}
1325
1326
/*****************************************************************************/
716
void APP_CC
1327
void APP_CC
717
g_delete_wait_obj_from_socket(tbus wait_obj)
1328
g_delete_wait_obj_from_socket(tbus wait_obj)
718
{
1329
{
1330
  MDBGLOG("net","INFO\t[%s()]: called (wait_obj = %d)",__func__,wait_obj);
719
#ifdef _WIN32
1331
#ifdef _WIN32
720
  if (wait_obj == 0)
1332
  if (wait_obj == 0)
721
  {
1333
  {
 Lines 737-748    Link Here 
737
    return 0;
1349
    return 0;
738
  }
1350
  }
739
  SetEvent((HANDLE)obj);
1351
  SetEvent((HANDLE)obj);
740
  return 0;
741
#else
1352
#else
742
  socklen_t sa_size;
1353
  socklen_t sa_size;
743
  int s;
1354
  int s;
744
  struct sockaddr_un sa;
1355
  struct sockaddr_un sa;
745
1356
1357
  //MDBGLOG("net","INFO\t[%s()]: called (obj = %d)",__func__,(int)obj);
1358
746
  if (obj == 0)
1359
  if (obj == 0)
747
  {
1360
  {
748
    return 0;
1361
    return 0;
 Lines 757-771    Link Here 
757
  {
1370
  {
758
    return 1;
1371
    return 1;
759
  }
1372
  }
760
  s = socket(PF_UNIX, SOCK_DGRAM, 0);
1373
  s = socket(PF_LOCAL, SOCK_DGRAM, 0);
761
  if (s < 0)
1374
  if (s < 0)
762
  {
1375
  {
763
    return 1;
1376
    return 1;
764
  }
1377
  }
765
  sendto(s, "sig", 4, 0, (struct sockaddr*)&sa, sa_size);
1378
  sendto(s, "sig", 4, 0, (struct sockaddr*)&sa, sa_size);
766
  close(s);
1379
  close(s);
767
  return 0;
768
#endif
1380
#endif
1381
  return 0;
769
}
1382
}
770
1383
771
/*****************************************************************************/
1384
/*****************************************************************************/
 Lines 773-798    Link Here 
773
int APP_CC
1386
int APP_CC
774
g_reset_wait_obj(tbus obj)
1387
g_reset_wait_obj(tbus obj)
775
{
1388
{
1389
  int rv = 0;
1390
  if (obj != 0) {
776
#ifdef _WIN32
1391
#ifdef _WIN32
777
  if (obj == 0)
1392
    ResetEvent((HANDLE)obj);
778
  {
779
    return 0;
780
  }
781
  ResetEvent((HANDLE)obj);
782
  return 0;
783
#else
1393
#else
784
  char buf[64];
1394
    char buf[64];
785
1395
    struct stat finfo;
786
  if (obj == 0)
1396
    g_memset(&finfo,0,sizeof(struct stat));
787
  {
1397
    fstat((int)obj, &finfo);
788
    return 0;
1398
    if (S_ISFIFO(finfo.st_mode) || S_ISREG(finfo.st_mode) || S_ISCHR(finfo.st_mode)) while (g_fifo_can_read((int)obj, 0)) {
789
  }
1399
      g_fifo_read((int)obj, buf, 64);//qqq
790
  while (g_tcp_can_recv((int)obj, 0))
1400
    }
791
  {
1401
    else if (S_ISSOCK(finfo.st_mode)) while (g_tcp_can_recv((int)obj, 0)) {
792
    recvfrom((int)obj, &buf, 64, 0, 0, 0);
1402
      g_tcp_recv(obj, buf, 64, 0);
793
  }
1403
      //recvfrom((int)obj, buf, 64, 0, 0, 0);
794
  return 0;
1404
    }
795
#endif
1405
#endif
1406
  }
1407
  return rv;
796
}
1408
}
797
1409
798
/*****************************************************************************/
1410
/*****************************************************************************/
 Lines 811-821    Link Here 
811
  }
1423
  }
812
  return 0;
1424
  return 0;
813
#else
1425
#else
814
  if (obj == 0)
1426
  int rv = 0;
815
  {
1427
  struct stat finfo;
816
    return 0;
1428
  g_memset(&finfo,0,sizeof(struct stat));
1429
  if (obj == 0) {
1430
    rv = 0;
817
  }
1431
  }
818
  return g_tcp_can_recv((int)obj, 0);
1432
  else {
1433
    fstat((int)obj, &finfo);
1434
    if (S_ISFIFO(finfo.st_mode) || S_ISREG(finfo.st_mode) || S_ISCHR(finfo.st_mode)) {
1435
      rv = g_fifo_can_read((int)obj, 0);
1436
    }
1437
    else if (S_ISSOCK(finfo.st_mode)) {
1438
      rv = g_tcp_can_recv((int)obj, 0);
1439
    }
1440
    else {
1441
      MDBGLOG("net","ERROR\t[%s()]: unrecognized FD type (finfo.st_mode = %d)",__func__,finfo.st_mode);
1442
      rv = -1;
1443
    }
1444
  }
1445
  return rv;
819
#endif
1446
#endif
820
}
1447
}
821
1448
 Lines 833-853    Link Here 
833
  CloseHandle((HANDLE)obj);
1460
  CloseHandle((HANDLE)obj);
834
  return 0;
1461
  return 0;
835
#else
1462
#else
1463
  struct stat finfo;
836
  socklen_t sa_size;
1464
  socklen_t sa_size;
837
  struct sockaddr_un sa;
1465
  struct sockaddr_un sa;
838
1466
839
  if (obj == 0)
1467
  MDBGLOG("net","INFO\t[%s()]: called (obj = %d)",__func__,(int)obj);
1468
1469
  if (obj < 0)
840
  {
1470
  {
841
    return 0;
1471
    return 0;
842
  }
1472
  }
843
  sa_size = sizeof(sa);
1473
844
  if (getsockname((int)obj, (struct sockaddr*)&sa, &sa_size) < 0)
1474
  fstat((int)obj, &finfo);
845
  {
1475
846
    return 1;
1476
  if (S_ISFIFO(finfo.st_mode)) {
1477
    close(obj);
1478
    unlink(SELFPIPE_PATH);
1479
    return 0;
1480
  }
1481
  else {
1482
    sa_size = sizeof(sa);
1483
    if (getsockname((int)obj, (struct sockaddr*)&sa, &sa_size) < 0)
1484
    {
1485
      return 1;
1486
    }
1487
    close((int)obj);
1488
    unlink(sa.sun_path);
1489
    return 0;
847
  }
1490
  }
848
  close((int)obj);
849
  unlink(sa.sun_path);
850
  return 0;
851
#endif
1491
#endif
852
}
1492
}
853
1493
 Lines 861-868    Link Here 
861
  HANDLE handles[256];
1501
  HANDLE handles[256];
862
  DWORD count;
1502
  DWORD count;
863
  DWORD error;
1503
  DWORD error;
864
  int j;
1504
  ptrdiff_t j;
865
  int i;
1505
  ptrdiff_t i;
866
1506
867
  j = 0;
1507
  j = 0;
868
  count = rcount + wcount;
1508
  count = rcount + wcount;
 Lines 888-902    Link Here 
888
  fd_set rfds;
1528
  fd_set rfds;
889
  fd_set wfds;
1529
  fd_set wfds;
890
  struct timeval time;
1530
  struct timeval time;
891
  struct timeval* ptime;
1531
  struct timeval* ptime = (struct timeval *)NULL;
892
  int i;
1532
  ptrdiff_t i = 0;
893
  int max;
1533
  int res = 0;
894
  int sck;
1534
  int max = 0;
1535
  tbus sck = 0;
1536
1537
  g_memset(&rfds,0,sizeof(fd_set));
1538
  g_memset(&wfds,0,sizeof(fd_set));
1539
  g_memset(&time,0,sizeof(struct timeval));
895
1540
896
  max = 0;
1541
  max = 0;
897
  if (mstimeout < 1)
1542
  if (mstimeout < 1)
898
  {
1543
  {
899
    ptime = 0;
1544
    ptime = (struct timeval *)NULL;
900
  }
1545
  }
901
  else
1546
  else
902
  {
1547
  {
 Lines 909-931    Link Here 
909
  for (i = 0; i < rcount; i++)
1554
  for (i = 0; i < rcount; i++)
910
  {
1555
  {
911
    sck = (int)(read_objs[i]);
1556
    sck = (int)(read_objs[i]);
912
    FD_SET(sck, &rfds);
1557
    if (sck > 0) {
913
    if (sck > max)
1558
      FD_SET(sck, &rfds);
914
    {
1559
      if (sck > max)
915
      max = sck;
1560
      {
1561
        max = sck;
1562
      }
916
    }
1563
    }
917
  }
1564
  }
918
  for (i = 0; i < wcount; i++)
1565
  for (i = 0; i < wcount; i++)
919
  {
1566
  {
920
    sck = (int)(write_objs[i]);
1567
    sck = (int)(write_objs[i]);
921
    FD_SET(sck, &wfds);
1568
    if (sck > 0) {
922
    if (sck > max)
1569
      FD_SET(sck, &wfds);
923
    {
1570
      if (sck > max)
924
      max = sck;
1571
      {
1572
        max = sck;
1573
      }
925
    }
1574
    }
926
  }
1575
  }
927
  i = select(max + 1, &rfds, &wfds, 0, ptime);
1576
  res = select(max + 1, &rfds, &wfds, 0, ptime);
928
  if (i < 0)
1577
  if (res < 0)
929
  {
1578
  {
930
    /* these are not really errors */
1579
    /* these are not really errors */
931
    if ((errno == EAGAIN) ||
1580
    if ((errno == EAGAIN) ||
 Lines 943-949    Link Here 
943
1592
944
/*****************************************************************************/
1593
/*****************************************************************************/
945
void APP_CC
1594
void APP_CC
946
g_random(char* data, int len)
1595
g_random(char * data, int len)
947
{
1596
{
948
#if defined(_WIN32)
1597
#if defined(_WIN32)
949
  int index;
1598
  int index;
 Lines 982-988    Link Here 
982
1631
983
/*****************************************************************************/
1632
/*****************************************************************************/
984
int APP_CC
1633
int APP_CC
985
g_memcmp(const void* s1, const void* s2, int len)
1634
g_memcmp(const void* s1, const void* s2, size_t len)
986
{
1635
{
987
  return memcmp(s1, s2, len);
1636
  return memcmp(s1, s2, len);
988
}
1637
}
 Lines 990-996    Link Here 
990
/*****************************************************************************/
1639
/*****************************************************************************/
991
/* returns -1 on error, else return handle or file descriptor */
1640
/* returns -1 on error, else return handle or file descriptor */
992
int APP_CC
1641
int APP_CC
993
g_file_open(const char* file_name)
1642
g_file_open(const char * file_name)
994
{
1643
{
995
#if defined(_WIN32)
1644
#if defined(_WIN32)
996
  return (int)CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE,
1645
  return (int)CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE,
 Lines 1006-1018    Link Here 
1006
    rv =  open(file_name, O_RDONLY);
1655
    rv =  open(file_name, O_RDONLY);
1007
  }
1656
  }
1008
  return rv;
1657
  return rv;
1009
#endif
1658
#endif
1659
}
1660
1661
/*****************************************************************************/
1662
/* returns -1 on error, else return handle or file descriptor */
1663
int APP_CC
1664
g_file_open_flags(const char * file_name, int oflag, mode_t omode) {
1665
  int rv = 0;
1666
  if (file_name == NULL || g_strlen(file_name) < 1) {
1667
    rv = -1;
1668
  }
1669
  else {
1670
#if defined(_WIN32)
1671
    rv = (int)CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE,
1672
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
1673
                          0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1674
#else
1675
    rv =  open(file_name, oflag, omode);
1676
#endif
1677
  }
1678
  return rv;
1679
}
1680
1681
/*****************************************************************************/
1682
void * APP_CC
1683
g_mmap(void * addr, size_t len, int prot, int flags, int fd, off_t offset) {
1684
#if defined(_WIN32)
1685
    return (void *)NULL;
1686
#else
1687
    return (len > 0) ? (void *)mmap(addr, len, prot, flags, fd, offset) : (void *)NULL;
1688
#endif
1689
}
1690
1691
/*****************************************************************************/
1692
void * APP_CC
1693
g_shmalloc(size_t len) {
1694
#if defined(_WIN32)
1695
    return (void *)NULL;
1696
#else
1697
    void * rv = (void *)NULL;
1698
    rv = g_mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
1699
    if (rv == NULL) {
1700
      int fd = 0;
1701
      const int oflag = O_RDWR | O_CREAT;
1702
      const mode_t omode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1703
      fd = g_file_open_flags("/dev/zero", oflag, omode);
1704
      if (fd > 0) {
1705
	rv = g_mmap((void *)NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
1706
	g_file_close(fd);
1707
      }
1708
    }
1709
    return rv;
1710
#endif
1711
}
1712
1713
/*****************************************************************************/
1714
int APP_CC
1715
g_shfree(void * addr, size_t len) {
1716
  if (addr != NULL && len > 0) {
1717
    return munmap(addr, len);
1718
  }
1719
  else {
1720
    return -1;
1721
  }
1722
}
1723
1724
/*****************************************************************************/
1725
/* returns -1 on error, else return handle or file descriptor */
1726
int APP_CC
1727
g_fifo_open(const char * file_name)
1728
{
1729
  int rv = -1;
1730
  char * fpath = (char *)NULL;
1731
  if (file_name == NULL || g_strlen(file_name) < 1) {
1732
    rv = -1;
1733
  }
1734
  else {
1735
    fpath = (char *)g_malloc(sizeof(char) * 512,1);
1736
#if defined(_WIN32)
1737
    g_snprintf(fpath,511,"\\\\.\\pipe\\%s",file_name);
1738
    rv = (int)CreateNamedPipeA(fpath,
1739
		(PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE),
1740
		(PIPE_TYPE_BYTE | PIPE_NOWAIT),
1741
		1,	/* nMaxInstances */
1742
		1024,	/* nOutBufferSize */
1743
		1024,	/* nInBufferSize */
1744
		0,	/* nDefaultTimeOut (milliseconds) */
1745
		NULL	/* lpSecurityAttributes */
1746
		);
1747
#else
1748
    g_snprintf(fpath,511,"%s",file_name);
1749
    /* The following statement works correctly under Linux,
1750
     * but its behavior is non-standard (the POSIX standard
1751
     * does not define what occurs when a FIFO is opened
1752
     * with the O_RDWR flag).
1753
     */
1754
//  rv = open(fpath, O_RDWR | O_NONBLOCK);
1755
    rv = open(fpath, O_RDWR);
1756
1757
    /* If the non-standard method does not work, then the
1758
     * following method is more POSIX-compliant; however, it
1759
     * may be susceptible to a potential race condition.
1760
     */
1761
    if (rv < 0) {
1762
      rv = open(fpath, O_RDONLY | O_NONBLOCK);
1763
      rv = open(fpath, O_WRONLY | O_NONBLOCK);
1764
    }
1765
#endif
1766
  }
1767
  MDBGLOG("net","INFO\t[%s()]: called (file_name = \"%s\", rv = %d)",__func__,((file_name == NULL || g_strlen(file_name) < 1) ? "(none)" : file_name),rv);
1768
  return rv;
1010
}
1769
}
1011
1770
1012
/*****************************************************************************/
1771
/*****************************************************************************/
1013
/* returns error, always 0 */
1772
/* returns error, always 0 */
1014
int APP_CC
1773
int APP_CC
1015
g_file_close(int fd)
1774
g_file_close(tbus fd)
1016
{
1775
{
1017
#if defined(_WIN32)
1776
#if defined(_WIN32)
1018
  CloseHandle((HANDLE)fd);
1777
  CloseHandle((HANDLE)fd);
 Lines 1024-1031    Link Here 
1024
1783
1025
/*****************************************************************************/
1784
/*****************************************************************************/
1026
/* read from file, returns the number of bytes read or -1 on error */
1785
/* read from file, returns the number of bytes read or -1 on error */
1027
int APP_CC
1786
ptrdiff_t APP_CC
1028
g_file_read(int fd, char* ptr, int len)
1787
g_file_read(tbus fd, char * ptr, size_t len)
1029
{
1788
{
1030
#if defined(_WIN32)
1789
#if defined(_WIN32)
1031
  if (ReadFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
1790
  if (ReadFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
 Lines 1034-1040    Link Here 
1034
  }
1793
  }
1035
  else
1794
  else
1036
  {
1795
  {
1037
    return -1;
1796
    return 0;
1038
  }
1797
  }
1039
#else
1798
#else
1040
  return read(fd, ptr, len);
1799
  return read(fd, ptr, len);
 Lines 1043-1050    Link Here 
1043
1802
1044
/*****************************************************************************/
1803
/*****************************************************************************/
1045
/* write to file, returns the number of bytes writen or -1 on error */
1804
/* write to file, returns the number of bytes writen or -1 on error */
1046
int APP_CC
1805
ptrdiff_t APP_CC
1047
g_file_write(int fd, char* ptr, int len)
1806
g_file_write(tbus fd, const char * ptr, size_t len)
1048
{
1807
{
1049
#if defined(_WIN32)
1808
#if defined(_WIN32)
1050
  if (WriteFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
1809
  if (WriteFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
 Lines 1053-1059    Link Here 
1053
  }
1812
  }
1054
  else
1813
  else
1055
  {
1814
  {
1056
    return -1;
1815
    return 0;
1057
  }
1816
  }
1058
#else
1817
#else
1059
  return write(fd, ptr, len);
1818
  return write(fd, ptr, len);
 Lines 1063-1069    Link Here 
1063
/*****************************************************************************/
1822
/*****************************************************************************/
1064
/* move file pointer, returns offset on success, -1 on failure */
1823
/* move file pointer, returns offset on success, -1 on failure */
1065
int APP_CC
1824
int APP_CC
1066
g_file_seek(int fd, int offset)
1825
g_file_seek(tbus fd, off_t offset)
1067
{
1826
{
1068
#if defined(_WIN32)
1827
#if defined(_WIN32)
1069
  int rv;
1828
  int rv;
 Lines 1086-1092    Link Here 
1086
/* do a write lock on a file */
1845
/* do a write lock on a file */
1087
/* return boolean */
1846
/* return boolean */
1088
int APP_CC
1847
int APP_CC
1089
g_file_lock(int fd, int start, int len)
1848
g_file_lock(tbus fd, off_t start, size_t len)
1090
{
1849
{
1091
#if defined(_WIN32)
1850
#if defined(_WIN32)
1092
  return LockFile((HANDLE)fd, start, 0, len, 0);
1851
  return LockFile((HANDLE)fd, start, 0, len, 0);
 Lines 1106-1114    Link Here 
1106
}
1865
}
1107
1866
1108
/*****************************************************************************/
1867
/*****************************************************************************/
1868
int APP_CC
1869
g_dir_create(const char * dirname, int flags)
1870
{
1871
  int rv = 0;
1872
1873
  if (g_strlen(dirname) > 0) {
1874
    if (!g_directory_exist(dirname)) {
1875
      rv = mkdir(dirname, flags);
1876
    }
1877
    else {
1878
      rv = -1;
1879
    }
1880
  }
1881
  else {
1882
    rv = -1;
1883
  }
1884
1885
  return rv;
1886
}
1887
1888
/*****************************************************************************/
1109
/* returns error */
1889
/* returns error */
1110
int APP_CC
1890
int APP_CC
1111
g_chmod_hex(const char* filename, int flags)
1891
g_chmod_hex(const char * filename, int flags)
1112
{
1892
{
1113
#if defined(_WIN32)
1893
#if defined(_WIN32)
1114
  return 0;
1894
  return 0;
 Lines 1135-1141    Link Here 
1135
/*****************************************************************************/
1915
/*****************************************************************************/
1136
/* returns error, always zero */
1916
/* returns error, always zero */
1137
int APP_CC
1917
int APP_CC
1138
g_mkdir(const char* dirname)
1918
g_mkdir(const char * dirname)
1139
{
1919
{
1140
#if defined(_WIN32)
1920
#if defined(_WIN32)
1141
  return 0;
1921
  return 0;
 Lines 1149-1156    Link Here 
1149
/* gets the current working directory and puts up to maxlen chars in
1929
/* gets the current working directory and puts up to maxlen chars in
1150
   dirname 
1930
   dirname 
1151
   always returns 0 */
1931
   always returns 0 */
1152
char* APP_CC
1932
char * APP_CC
1153
g_get_current_dir(char* dirname, int maxlen)
1933
g_get_current_dir(char * dirname, size_t maxlen)
1154
{
1934
{
1155
#if defined(_WIN32)
1935
#if defined(_WIN32)
1156
  GetCurrentDirectoryA(maxlen, dirname);
1936
  GetCurrentDirectoryA(maxlen, dirname);
 Lines 1166-1172    Link Here 
1166
/*****************************************************************************/
1946
/*****************************************************************************/
1167
/* returns error, zero on success and -1 on failure */
1947
/* returns error, zero on success and -1 on failure */
1168
int APP_CC
1948
int APP_CC
1169
g_set_current_dir(char* dirname)
1949
g_set_current_dir(const char * dirname)
1170
{
1950
{
1171
#if defined(_WIN32)
1951
#if defined(_WIN32)
1172
  if (SetCurrentDirectoryA(dirname))
1952
  if (SetCurrentDirectoryA(dirname))
 Lines 1185-1191    Link Here 
1185
/*****************************************************************************/
1965
/*****************************************************************************/
1186
/* returns boolean, non zero if the file exists */
1966
/* returns boolean, non zero if the file exists */
1187
int APP_CC
1967
int APP_CC
1188
g_file_exist(const char* filename)
1968
g_file_exist(const char * filename)
1189
{
1969
{
1190
#if defined(_WIN32)
1970
#if defined(_WIN32)
1191
  return 0; // use FileAge(filename) <> -1
1971
  return 0; // use FileAge(filename) <> -1
 Lines 1197-1203    Link Here 
1197
/*****************************************************************************/
1977
/*****************************************************************************/
1198
/* returns boolean, non zero if the directory exists */
1978
/* returns boolean, non zero if the directory exists */
1199
int APP_CC
1979
int APP_CC
1200
g_directory_exist(const char* dirname)
1980
g_directory_exist(const char * dirname)
1201
{
1981
{
1202
#if defined(_WIN32)
1982
#if defined(_WIN32)
1203
  return 0; // use GetFileAttributes and check return value
1983
  return 0; // use GetFileAttributes and check return value
 Lines 1219-1225    Link Here 
1219
/*****************************************************************************/
1999
/*****************************************************************************/
1220
/* returns boolean */
2000
/* returns boolean */
1221
int APP_CC
2001
int APP_CC
1222
g_create_dir(const char* dirname)
2002
g_create_dir(const char * dirname)
1223
{
2003
{
1224
#if defined(_WIN32)
2004
#if defined(_WIN32)
1225
  return CreateDirectoryA(dirname, 0); // test this
2005
  return CreateDirectoryA(dirname, 0); // test this
 Lines 1231-1237    Link Here 
1231
/*****************************************************************************/
2011
/*****************************************************************************/
1232
/* returns boolean */
2012
/* returns boolean */
1233
int APP_CC
2013
int APP_CC
1234
g_remove_dir(const char* dirname)
2014
g_remove_dir(const char * dirname)
1235
{
2015
{
1236
#if defined(_WIN32)
2016
#if defined(_WIN32)
1237
  return RemoveDirectoryA(dirname); // test this
2017
  return RemoveDirectoryA(dirname); // test this
 Lines 1243-1249    Link Here 
1243
/*****************************************************************************/
2023
/*****************************************************************************/
1244
/* returns non zero if the file was deleted */
2024
/* returns non zero if the file was deleted */
1245
int APP_CC
2025
int APP_CC
1246
g_file_delete(const char* filename)
2026
g_file_delete(const char * filename)
1247
{
2027
{
1248
#if defined(_WIN32)
2028
#if defined(_WIN32)
1249
  return DeleteFileA(filename);
2029
  return DeleteFileA(filename);
 Lines 1254-1261    Link Here 
1254
2034
1255
/*****************************************************************************/
2035
/*****************************************************************************/
1256
/* returns file size, -1 on error */
2036
/* returns file size, -1 on error */
1257
int APP_CC
2037
size_t APP_CC
1258
g_file_get_size(const char* filename)
2038
g_file_get_size(const char * filename)
1259
{
2039
{
1260
#if defined(_WIN32)
2040
#if defined(_WIN32)
1261
  return -1;
2041
  return -1;
 Lines 1275-1284    Link Here 
1275
2055
1276
/*****************************************************************************/
2056
/*****************************************************************************/
1277
/* returns length of text */
2057
/* returns length of text */
1278
int APP_CC
2058
size_t APP_CC
1279
g_strlen(const char* text)
2059
g_strlen(const char * text)
1280
{
2060
{
1281
  if (text == 0)
2061
  if (text == NULL)
1282
  {
2062
  {
1283
    return 0;
2063
    return 0;
1284
  }
2064
  }
 Lines 1286-1294    Link Here 
1286
}
2066
}
1287
2067
1288
/*****************************************************************************/
2068
/*****************************************************************************/
2069
/* returns length of text, up to a maximum value */
2070
size_t APP_CC
2071
g_strnlen(const char * text, size_t maxlen)
2072
{
2073
  int rv = 0;
2074
  if (text == NULL || maxlen < 1) {
2075
    rv = 0;
2076
  }
2077
  else {
2078
    rv = strlen(text);
2079
    if (rv > maxlen) {
2080
      rv = maxlen;
2081
    }
2082
  }
2083
  return rv;
2084
}
2085
2086
/*****************************************************************************/
2087
char * APP_CC
2088
g_strstr(const char * s1, const char * s2)
2089
{
2090
  char * rv = (char *)NULL;
2091
  if ((s1 != NULL) && (s2 != NULL)) {
2092
    rv = strstr(s1,s2);
2093
  }
2094
  return rv;
2095
}
2096
2097
/*****************************************************************************/
2098
char * APP_CC
2099
g_strchr(const char * s, int c)
2100
{
2101
  char * rv = (char *)NULL;
2102
  if (s != NULL) {
2103
    rv = strchr(s,c);
2104
  }
2105
  return rv;
2106
}
2107
2108
/*****************************************************************************/
2109
char * APP_CC
2110
g_strrchr(const char * s, int c)
2111
{
2112
  char * rv = (char *)NULL;
2113
  if (s != NULL) {
2114
    rv = strrchr(s,c);
2115
  }
2116
  return rv;
2117
}
2118
2119
/*****************************************************************************/
1289
/* returns dest */
2120
/* returns dest */
1290
char* APP_CC
2121
char * APP_CC
1291
g_strcpy(char* dest, const char* src)
2122
g_strcpy(char * dest, const char * src)
1292
{
2123
{
1293
  if (src == 0 && dest != 0)
2124
  if (src == 0 && dest != 0)
1294
  {
2125
  {
 Lines 1304-1313    Link Here 
1304
2135
1305
/*****************************************************************************/
2136
/*****************************************************************************/
1306
/* returns dest */
2137
/* returns dest */
1307
char* APP_CC
2138
char * APP_CC
1308
g_strncpy(char* dest, const char* src, int len)
2139
g_strncpy(char * dest, const char * src, size_t len)
1309
{
2140
{
1310
  char* rv;
2141
  char * rv;
1311
2142
1312
  if (src == 0 && dest != 0)
2143
  if (src == 0 && dest != 0)
1313
  {
2144
  {
 Lines 1325-1332    Link Here 
1325
2156
1326
/*****************************************************************************/
2157
/*****************************************************************************/
1327
/* returns dest */
2158
/* returns dest */
1328
char* APP_CC
2159
char * APP_CC
1329
g_strcat(char* dest, const char* src)
2160
g_strcat(char * dest, const char * src)
1330
{
2161
{
1331
  if (dest == 0 || src == 0)
2162
  if (dest == 0 || src == 0)
1332
  {
2163
  {
 Lines 1336-1375    Link Here 
1336
}
2167
}
1337
2168
1338
/*****************************************************************************/
2169
/*****************************************************************************/
2170
/* returns dest */
2171
char * APP_CC
2172
g_strncat(char * dest, const char * src, size_t lmt)
2173
{
2174
  if (dest == 0 || src == 0)
2175
  {
2176
    return dest;
2177
  }
2178
  return strncat(dest, src, lmt);
2179
}
2180
2181
/*****************************************************************************/
1339
/* if in = 0, return 0 else return newly alloced copy of in */
2182
/* if in = 0, return 0 else return newly alloced copy of in */
1340
char* APP_CC
2183
char * APP_CC
1341
g_strdup(const char* in)
2184
g_strdup(const char * in)
1342
{
2185
{
1343
  int len;
2186
  int len;
1344
  char* p;
2187
  char * p;
1345
2188
1346
  if (in == 0)
2189
  if (in == 0)
1347
  {
2190
  {
1348
    return 0;
2191
    return 0;
1349
  }
2192
  }
1350
  len = g_strlen(in);
2193
  len = g_strlen(in);
1351
  p = (char*)g_malloc(len + 1, 0);
2194
  p = (char *)g_malloc(len + 1, 0);
1352
  g_strcpy(p, in);
2195
  if (p != NULL) {
2196
    g_strcpy(p, in);
2197
  }
2198
  return p;
2199
}
2200
2201
/*****************************************************************************/
2202
char * APP_CC
2203
g_strndup(const char * in, size_t size) {
2204
  int len = 0;
2205
  char * p = (char *)NULL;
2206
2207
#if !defined(MINVAL)
2208
#define MINVAL(x,y) (((x) > (y)) ? (y) : (x))
2209
#define __NOMINVAL
2210
#endif
2211
2212
  if (in == NULL) {
2213
    return 0;
2214
  }
2215
  len = MINVAL(g_strlen(in),size);
2216
  p = (char *)g_malloc((len + 1), 1);
2217
  if (p != NULL) {
2218
    g_strncpy(p, in, len);
2219
  }
1353
  return p;
2220
  return p;
2221
2222
#if defined(__NOMINVAL)
2223
#undef MINVAL
2224
#endif
2225
}
2226
2227
2228
/*****************************************************************************/
2229
#define m_strdup_printf(fmtstr, ...) {		\
2230
  char p[1024];					\
2231
  g_memset(p,0,1024);				\
2232
  g_snprintf(p,1023,fmtstr, __VA_ARGS__);	\
2233
  return p;					\
1354
}
2234
}
1355
2235
1356
/*****************************************************************************/
2236
/*****************************************************************************/
1357
int APP_CC
2237
int APP_CC
1358
g_strcmp(const char* c1, const char* c2)
2238
g_strcmp(const char * c1, const char * c2)
1359
{
2239
{
1360
  return strcmp(c1, c2);
2240
  return strcmp(c1, c2);
1361
}
2241
}
1362
2242
1363
/*****************************************************************************/
2243
/*****************************************************************************/
1364
int APP_CC
2244
int APP_CC
1365
g_strncmp(const char* c1, const char* c2, int len)
2245
g_strncmp(const char * c1, const char * c2, size_t len)
1366
{
2246
{
1367
  return strncmp(c1, c2, len);
2247
  return strncmp(c1, c2, len);
1368
}
2248
}
1369
2249
1370
/*****************************************************************************/
2250
/*****************************************************************************/
1371
int APP_CC
2251
int APP_CC
1372
g_strcasecmp(const char* c1, const char* c2)
2252
g_strcasecmp(const char * c1, const char * c2)
1373
{
2253
{
1374
#if defined(_WIN32)
2254
#if defined(_WIN32)
1375
  return stricmp(c1, c2);
2255
  return stricmp(c1, c2);
 Lines 1380-1386    Link Here 
1380
2260
1381
/*****************************************************************************/
2261
/*****************************************************************************/
1382
int APP_CC
2262
int APP_CC
1383
g_strncasecmp(const char* c1, const char* c2, int len)
2263
g_strncasecmp(const char * c1, const char * c2, size_t len)
1384
{
2264
{
1385
#if defined(_WIN32)
2265
#if defined(_WIN32)
1386
  return strnicmp(c1, c2, len);
2266
  return strnicmp(c1, c2, len);
 Lines 1391-1397    Link Here 
1391
2271
1392
/*****************************************************************************/
2272
/*****************************************************************************/
1393
int APP_CC
2273
int APP_CC
1394
g_atoi(char* str)
2274
g_atoi(char * str)
1395
{
2275
{
1396
  if (str == 0)
2276
  if (str == 0)
1397
  {
2277
  {
 Lines 1402-1417    Link Here 
1402
2282
1403
/*****************************************************************************/
2283
/*****************************************************************************/
1404
int APP_CC
2284
int APP_CC
1405
g_htoi(char* str)
2285
g_htoi(char * str)
1406
{
2286
{
1407
  int len;
2287
  size_t len;
1408
  int index;
2288
  ptrdiff_t index;
1409
  int rv;
2289
  int rv;
1410
  int val;
2290
  int val;
1411
  int shift;
2291
  int shift;
1412
2292
1413
  rv = 0;
2293
  rv = 0;
1414
  len = strlen(str);
2294
  len = g_strlen(str);
1415
  index = len - 1;
2295
  index = len - 1;
1416
  shift = 0;
2296
  shift = 0;
1417
  while (index >= 0)
2297
  while (index >= 0)
 Lines 1480-1488    Link Here 
1480
2360
1481
/*****************************************************************************/
2361
/*****************************************************************************/
1482
int APP_CC
2362
int APP_CC
1483
g_pos(char* str, const char* to_find)
2363
g_pos(char * str, const char * to_find)
1484
{
2364
{
1485
  char* pp;
2365
  char * pp;
1486
2366
1487
  pp = strstr(str, to_find);
2367
  pp = strstr(str, to_find);
1488
  if (pp == 0)
2368
  if (pp == 0)
 Lines 1494-1500    Link Here 
1494
2374
1495
/*****************************************************************************/
2375
/*****************************************************************************/
1496
int APP_CC
2376
int APP_CC
1497
g_mbstowcs(twchar* dest, const char* src, int n)
2377
g_mbstowcs(twchar * dest, const char * src, int n)
1498
{
2378
{
1499
  wchar_t* ldest;
2379
  wchar_t* ldest;
1500
  int rv;
2380
  int rv;
 Lines 1506-1512    Link Here 
1506
2386
1507
/*****************************************************************************/
2387
/*****************************************************************************/
1508
int APP_CC
2388
int APP_CC
1509
g_wcstombs(char* dest, const twchar* src, int n)
2389
g_wcstombs(char * dest, const twchar * src, int n)
1510
{
2390
{
1511
  const wchar_t* lsrc;
2391
  const wchar_t* lsrc;
1512
  int rv;
2392
  int rv;
 Lines 1522-1535    Link Here 
1522
/* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */
2402
/* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */
1523
/* this will always shorten the string or not change it */
2403
/* this will always shorten the string or not change it */
1524
int APP_CC
2404
int APP_CC
1525
g_strtrim(char* str, int trim_flags)
2405
g_strtrim(char * str, int trim_flags)
1526
{
2406
{
1527
  int index;
2407
  ptrdiff_t index = 0;
1528
  int len;
2408
  size_t len = 0;
1529
  int text1_index;
2409
  ptrdiff_t text1_index = 0;
1530
  int got_char;
2410
  int got_char = 0;
1531
  wchar_t* text;
2411
  wchar_t * text = (wchar_t *)NULL;
1532
  wchar_t* text1;
2412
  wchar_t * text1 = (wchar_t *)NULL;
1533
2413
1534
  len = mbstowcs(0, str, 0);
2414
  len = mbstowcs(0, str, 0);
1535
  if (len < 1)
2415
  if (len < 1)
 Lines 1637-1643    Link Here 
1637
2517
1638
/*****************************************************************************/
2518
/*****************************************************************************/
1639
long APP_CC
2519
long APP_CC
1640
g_load_library(char* in)
2520
g_load_library(char * in)
1641
{
2521
{
1642
#if defined(_WIN32)
2522
#if defined(_WIN32)
1643
  return (long)LoadLibraryA(in);
2523
  return (long)LoadLibraryA(in);
 Lines 1664-1670    Link Here 
1664
/*****************************************************************************/
2544
/*****************************************************************************/
1665
/* returns NULL if not found */
2545
/* returns NULL if not found */
1666
void* APP_CC
2546
void* APP_CC
1667
g_get_proc_address(long lib, const char* name)
2547
g_get_proc_address(long lib, const char * name)
1668
{
2548
{
1669
  if (lib == 0)
2549
  if (lib == 0)
1670
  {
2550
  {
 Lines 1680-1686    Link Here 
1680
/*****************************************************************************/
2560
/*****************************************************************************/
1681
/* does not work in win32 */
2561
/* does not work in win32 */
1682
int APP_CC
2562
int APP_CC
1683
g_system(char* aexec)
2563
g_system(char * aexec)
1684
{
2564
{
1685
#if defined(_WIN32)
2565
#if defined(_WIN32)
1686
  return 0;
2566
  return 0;
 Lines 1691-1697    Link Here 
1691
2571
1692
/*****************************************************************************/
2572
/*****************************************************************************/
1693
/* does not work in win32 */
2573
/* does not work in win32 */
1694
char* APP_CC
2574
char * APP_CC
1695
g_get_strerror(void)
2575
g_get_strerror(void)
1696
{
2576
{
1697
#if defined(_WIN32)
2577
#if defined(_WIN32)
 Lines 1715-1721    Link Here 
1715
/*****************************************************************************/
2595
/*****************************************************************************/
1716
/* does not work in win32 */
2596
/* does not work in win32 */
1717
int APP_CC
2597
int APP_CC
1718
g_execvp(const char* p1, char* args[])
2598
g_execvp(const char * p1, char * args[])
1719
{
2599
{
1720
#if defined(_WIN32)
2600
#if defined(_WIN32)
1721
  return 0;
2601
  return 0;
 Lines 1727-1733    Link Here 
1727
/*****************************************************************************/
2607
/*****************************************************************************/
1728
/* does not work in win32 */
2608
/* does not work in win32 */
1729
int APP_CC
2609
int APP_CC
1730
g_execlp3(const char* a1, const char* a2, const char* a3)
2610
g_execlp3(const char * a1, const char * a2, const char * a3)
1731
{
2611
{
1732
#if defined(_WIN32)
2612
#if defined(_WIN32)
1733
  return 0;
2613
  return 0;
 Lines 1830-1836    Link Here 
1830
/* returns error, zero is success, non zero is error */
2710
/* returns error, zero is success, non zero is error */
1831
/* does not work in win32 */
2711
/* does not work in win32 */
1832
int APP_CC
2712
int APP_CC
1833
g_initgroups(const char* user, int gid)
2713
g_initgroups(const char * user, int gid)
1834
{
2714
{
1835
#if defined(_WIN32)
2715
#if defined(_WIN32)
1836
  return 0;
2716
  return 0;
 Lines 1898-1911    Link Here 
1898
#if defined(_WIN32)
2778
#if defined(_WIN32)
1899
  return 0;
2779
  return 0;
1900
#else
2780
#else
1901
  int rv;
2781
  int rv = 0;
1902
2782
  if (pid < 0) {
1903
  rv = waitpid(pid, 0, 0);
2783
    rv = -1;
1904
  if (rv == -1)
2784
  }
1905
  {
2785
  else {
1906
    if (errno == EINTR) /* signal occurred */
2786
    rv = waitpid(pid, 0, 0);
2787
    if (rv == -1)
1907
    {
2788
    {
1908
      rv = 0;
2789
      if (errno == EINTR) /* signal occurred */
2790
      {
2791
	rv = 0;
2792
      }
1909
    }
2793
    }
1910
  }
2794
  }
1911
  return rv;
2795
  return rv;
 Lines 1926-1932    Link Here 
1926
/*****************************************************************************/
2810
/*****************************************************************************/
1927
/* does not work in win32 */
2811
/* does not work in win32 */
1928
int APP_CC
2812
int APP_CC
1929
g_setenv(const char* name, const char* value, int rewrite)
2813
g_setenv(const char * name, const char * value, int rewrite)
1930
{
2814
{
1931
#if defined(_WIN32)
2815
#if defined(_WIN32)
1932
  return 0;
2816
  return 0;
 Lines 1937-1944    Link Here 
1937
2821
1938
/*****************************************************************************/
2822
/*****************************************************************************/
1939
/* does not work in win32 */
2823
/* does not work in win32 */
1940
char* APP_CC
2824
char * APP_CC
1941
g_getenv(const char* name)
2825
g_getenv(const char * name)
1942
{
2826
{
1943
#if defined(_WIN32)
2827
#if defined(_WIN32)
1944
  return 0;
2828
  return 0;
 Lines 1967-1972    Link Here 
1967
}
2851
}
1968
2852
1969
/*****************************************************************************/
2853
/*****************************************************************************/
2854
int APP_CC
2855
g_gettid(void)
2856
{
2857
#if defined(_WIN32)
2858
  return (int)GetCurrentThreadId();
2859
#else
2860
#if defined(__linux__)
2861
  return syscall(SYS_gettid);
2862
#else
2863
  return (int)pthread_self();
2864
#endif
2865
#endif
2866
}
2867
2868
/*****************************************************************************/
1970
/* does not work in win32 */
2869
/* does not work in win32 */
1971
int APP_CC
2870
int APP_CC
1972
g_sigterm(int pid)
2871
g_sigterm(int pid)
 Lines 1982-1989    Link Here 
1982
/* returns 0 if ok */
2881
/* returns 0 if ok */
1983
/* does not work in win32 */
2882
/* does not work in win32 */
1984
int APP_CC
2883
int APP_CC
1985
g_getuser_info(const char* username, int* gid, int* uid, char* shell,
2884
g_getuser_info(const char * username, int* gid, int* uid, char * shell,
1986
               char* dir, char* gecos)
2885
               char * dir, char * gecos)
1987
{
2886
{
1988
#if defined(_WIN32)
2887
#if defined(_WIN32)
1989
  return 1;
2888
  return 1;
 Lines 2023-2029    Link Here 
2023
/* returns 0 if ok */
2922
/* returns 0 if ok */
2024
/* does not work in win32 */
2923
/* does not work in win32 */
2025
int APP_CC
2924
int APP_CC
2026
g_getgroup_info(const char* groupname, int* gid)
2925
g_getgroup_info(const char * groupname, int* gid)
2027
{
2926
{
2028
#if defined(_WIN32)
2927
#if defined(_WIN32)
2029
  return 1;
2928
  return 1;
 Lines 2048-2060    Link Here 
2048
/* if zero is returned, then ok is set */
2947
/* if zero is returned, then ok is set */
2049
/* does not work in win32 */
2948
/* does not work in win32 */
2050
int APP_CC
2949
int APP_CC
2051
g_check_user_in_group(const char* username, int gid, int* ok)
2950
g_check_user_in_group(const char * username, int gid, int* ok)
2052
{
2951
{
2053
#if defined(_WIN32)
2952
#if defined(_WIN32)
2054
  return 1;
2953
  return 1;
2055
#else
2954
#else
2056
  struct group* groups;
2955
  struct group * groups = (struct group *)NULL;
2057
  int i;
2956
  ptrdiff_t i = 0;
2058
2957
2059
  groups = getgrgid(gid);
2958
  groups = getgrgid(gid);
2060
  if (groups == 0)
2959
  if (groups == 0)
 Lines 2082-2087    Link Here 
2082
   for windows, returns the number of seconds since the machine was
2981
   for windows, returns the number of seconds since the machine was
2083
   started. */
2982
   started. */
2084
int APP_CC
2983
int APP_CC
2984
g_time(time_t * tval)
2985
{
2986
#if defined(_WIN32)
2987
  return GetTickCount() / 1000;
2988
#else
2989
  return time(tval);
2990
#endif
2991
}
2992
2993
/*****************************************************************************/
2994
/* returns the time since the Epoch (00:00:00 UTC, January 1, 1970),
2995
   measured in seconds.
2996
   for windows, returns the number of seconds since the machine was
2997
   started. */
2998
int APP_CC
2085
g_time1(void)
2999
g_time1(void)
2086
{
3000
{
2087
#if defined(_WIN32)
3001
#if defined(_WIN32)
 Lines 2094-2110    Link Here 
2094
/*****************************************************************************/
3008
/*****************************************************************************/
2095
/* returns the number of milliseconds since the machine was
3009
/* returns the number of milliseconds since the machine was
2096
   started. */
3010
   started. */
2097
int APP_CC
3011
long int APP_CC
2098
g_time2(void)
3012
g_time2(void)
2099
{
3013
{
2100
#if defined(_WIN32)
3014
#if defined(_WIN32)
2101
  return (int)GetTickCount();
3015
  return (int)GetTickCount();
2102
#else
3016
#else
2103
  struct tms tm;
3017
  struct tms tm;
2104
  clock_t num_ticks;
3018
  clock_t num_ticks = 0;
2105
3019
  g_memset(&tm,0,sizeof(struct tms));
2106
  num_ticks = times(&tm);
3020
  num_ticks = times(&tm);
2107
  return (int)(num_ticks * 10);
3021
  return (long int)(num_ticks * 10);
2108
#endif
3022
#endif
2109
}
3023
}
2110
3024
 Lines 2123-2125    Link Here 
2123
  return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
3037
  return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
2124
#endif
3038
#endif
2125
}
3039
}
3040
3041
/*****************************************************************************/
3042
/* returns list of files in a directory */
3043
char ** APP_CC
3044
g_dir_list_contents(const char * dirname, char ** contents, int * count) {
3045
  DIR * dp = (DIR *)NULL;
3046
  struct dirent * ep = (struct dirent *)NULL;
3047
  strlist * lst = (strlist *)NULL;
3048
  lst = strlist_init();
3049
  if (g_strlen(dirname)>0) {
3050
    dp = opendir (dirname);
3051
  }
3052
  if (dp != NULL) {
3053
    while ((ep = readdir(dp)) > 0) {
3054
      if (g_strlen(ep->d_name) > 0) {
3055
	lst = strlist_append(&lst, ep->d_name);
3056
      }
3057
    }
3058
    (void) closedir (dp);
3059
  }
3060
  contents = strlist_to_array(lst,count);
3061
  return contents;
3062
}
3063
3064
3065
/*****************************************************************************/
3066
/* Subtract the "struct timeval" values X and Y,
3067
   that is, subtract Y from X, storing the result in RESULT.
3068
   Return 1 if the difference is negative, otherwise 0.  */
3069
int APP_CC
3070
timeval_subtract (result, x, y) struct timeval *result, *x, *y;
3071
{
3072
  /* Perform the carry for the later subtraction by updating y. */
3073
  if (x->tv_usec < y->tv_usec) {
3074
    int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
3075
    y->tv_usec -= 1000000 * nsec;
3076
    y->tv_sec += nsec;
3077
  }
3078
  if (x->tv_usec - y->tv_usec > 1000000) {
3079
    int nsec = (x->tv_usec - y->tv_usec) / 1000000;
3080
    y->tv_usec += 1000000 * nsec;
3081
    y->tv_sec -= nsec;
3082
  }
3083
3084
  /* Compute the time remaining to wait.
3085
     tv_usec is certainly positive. */
3086
  result->tv_sec = x->tv_sec - y->tv_sec;
3087
  result->tv_usec = x->tv_usec - y->tv_usec;
3088
3089
  /* Return 1 if result is negative. */
3090
  return x->tv_sec < y->tv_sec;
3091
}
3092
3093
#define ONE_MILLION	1000000
3094
3095
/**
3096
 * Make a timeval value.
3097
 * 
3098
 * @param sec the number of seconds.
3099
 * @param usec the number of microseconds.
3100
 * @return the timeval value of @ref sec and @ref usec.
3101
 */
3102
inline struct timeval
3103
mk_timeval(int sec, int usec)
3104
{
3105
    struct timeval t;
3106
    t.tv_sec = sec;
3107
    t.tv_usec = usec;
3108
    return t;
3109
}
3110
3111
/**
3112
 * Adjust the timeval value so it is valid.
3113
 * 
3114
 * A timeval value is valid if the number of microseconds is not negative,
3115
 * and is smaller than 1000000 (i.e., one million).
3116
 * 
3117
 * @param t the timeval value to adjust.
3118
 * @return the adjusted timeval value. Note that the original @ref t value
3119
 * is also adjusted.
3120
 */
3121
inline struct timeval *
3122
timeval_round(struct timeval * t)
3123
{
3124
    if (t->tv_usec < 0) {
3125
	t->tv_usec += ONE_MILLION ;
3126
	t->tv_sec -- ;
3127
    } else if (t->tv_usec >= ONE_MILLION) {
3128
	t->tv_usec -= ONE_MILLION ;
3129
	t->tv_sec ++ ;
3130
    }
3131
    return t;
3132
}
3133
3134
/**
3135
 * Convert a timeval value to a double-float value.
3136
 * 
3137
 * @param t the timeval value to convert to a double-float value.
3138
 * @return the double-float value of @ref t.
3139
 */
3140
inline double
3141
timeval_to_double(const struct timeval * t)
3142
{
3143
    return t->tv_sec * 1.0 + t->tv_usec * 1.0e-6;
3144
}
3145
3146
/**
3147
 * Convert a double-float value to a timeval value.
3148
 * 
3149
 * @param d the double-float value to convert to a timeval value.
3150
 * @return the timeval value of @ref.
3151
 */
3152
inline struct timeval
3153
double_to_timeval(const double * d)
3154
{
3155
    double tmp = 0.;
3156
    struct timeval t;
3157
    t.tv_sec = (int)*d;
3158
    tmp = *d - (double)t.tv_sec;
3159
    t.tv_usec = (int)(tmp * ONE_MILLION);
3160
    return t;
3161
}
3162
3163
3164
/***	iconv functions:	***/
3165
3166
int APP_CC
3167
g_iconv_init() {
3168
  int rv = 0;
3169
  const char platform_encoding[] = "UTF-8";
3170
  const char rdp_encoding[] = "UTF-16LE";
3171
3172
  pthread_mutex_init(&g_mutex_iconv,NULL);
3173
3174
  pthread_mutex_lock(&g_mutex_iconv);
3175
  if (g_icd == (iconv_t)(-1)) {
3176
    g_icd = iconv_open(platform_encoding,rdp_encoding);
3177
  }
3178
  if (g_ocd == (iconv_t)(-1)) {
3179
    g_ocd = iconv_open(rdp_encoding,platform_encoding);
3180
  }
3181
  pthread_mutex_unlock(&g_mutex_iconv);
3182
3183
  return rv;
3184
}
3185
3186
int APP_CC
3187
g_iconv_end() {
3188
  int rv = 0;
3189
3190
  pthread_mutex_lock(&g_mutex_iconv);
3191
  if (g_icd > (iconv_t)(-1)) {
3192
    iconv_close(g_icd);
3193
    g_icd = (iconv_t)(-1);
3194
  }
3195
  if (g_ocd > (iconv_t)(-1)) {
3196
    iconv_close(g_ocd);
3197
    g_ocd = (iconv_t)(-1);
3198
  }
3199
  pthread_mutex_unlock(&g_mutex_iconv);
3200
3201
  pthread_mutex_destroy(&g_mutex_iconv);
3202
3203
  return rv;
3204
}
3205
3206
int APP_CC
3207
g_instr(char ** ostr, int * olen, char ** istr, int * ilen) {
3208
  int rv = 0;
3209
3210
  pthread_mutex_lock(&g_mutex_iconv);
3211
  iconv(g_icd, istr, (size_t *)ilen, ostr, (size_t *)olen);
3212
  
3213
  *ostr = '\0';
3214
  pthread_mutex_unlock(&g_mutex_iconv);
3215
3216
  return rv;
3217
}
3218
3219
int APP_CC
3220
g_outstr(char ** ostr, int * olen, char ** istr, int * ilen) {
3221
  int rv = 0;
3222
3223
  pthread_mutex_lock(&g_mutex_iconv);
3224
  iconv(g_ocd, istr, (size_t *)ilen, ostr, (size_t *)olen);
3225
  *ostr = '\0';
3226
  pthread_mutex_unlock(&g_mutex_iconv);
3227
3228
  return rv;
3229
}
3230
3231
/****					****/
3232
/****	Timestamp conversion		****/
3233
/****					****/
3234
3235
/* Convert a UNIX time_t into a Windows filetime_t */
3236
filetime_t UnixToFileTime(time_t utime) {
3237
        int64_t tconv = ((int64_t)utime * RATE_DIFF) + EPOCH_DIFF;
3238
        return tconv;
3239
}
3240
3241
/* Convert a Windows filetime_t into a UNIX time_t */
3242
time_t FileTimeToUnix(filetime_t ftime) {
3243
        int64_t tconv = (ftime - EPOCH_DIFF) / RATE_DIFF;
3244
        return (time_t)tconv;
3245
}
3246
3247
/* g_strsep() */
3248
char * g_strsep(char ** stringp, const char * delim) {
3249
  char * rv = (char *)NULL;
3250
3251
  if (stringp != NULL && *stringp != NULL && delim != NULL && g_strlen(delim) > 0) {
3252
    rv = strsep(stringp, delim);
3253
  }
3254
3255
  return rv;
3256
}
3257
3258
/*****************************************************************************/
3259
int APP_CC
3260
g_mkfifo(const char * iname, mode_t imode) {
3261
  int rv = 0;
3262
  char * fname = (char *)NULL;
3263
  mode_t fmode = 0;
3264
3265
  if (iname == NULL || g_strlen(iname) < 1) {
3266
    rv = -1;
3267
  }
3268
  else {
3269
    fmode = imode;
3270
    fname = g_strdup(iname);
3271
    rv = mkfifo(fname, fmode);
3272
  }
3273
3274
  return rv;
3275
}
3276
3277
/*****************************************************************************/
3278
int APP_CC
3279
g_mknod(const char * iname, mode_t imode, dev_t idev) {
3280
  int rv = 0;
3281
  char * fname = (char *)NULL;
3282
  mode_t fmode = 0;
3283
  dev_t fdev = 0;
3284
3285
  if (iname == NULL || g_strlen(iname) < 1) {
3286
    rv = -1;
3287
  }
3288
  else {
3289
    fmode = imode;
3290
    fdev = idev;
3291
    fname = g_strdup(iname);
3292
    rv = mknod(fname, fmode, fdev);
3293
  }
3294
3295
  return rv;
3296
}
3297
3298
#if defined(XRDP_ENABLE_NETLINK)
3299
3300
/*****************************************************************************/
3301
int APP_CC
3302
g_netlink_socket(void) {
3303
  DBGLOG("net","[os_calls]->g_netlink_socket() called");
3304
#if defined(_WIN32)
3305
  return 0;
3306
#else
3307
  return socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
3308
#endif
3309
}
3310
3311
/*****************************************************************************/
3312
void APP_CC
3313
g_netlink_close(tbus sck) {
3314
  DBGLOG("net","[os_calls]->g_netlink_close() called");
3315
  if (sck != 0)
3316
  {
3317
#if defined(_WIN32)
3318
#else
3319
    close(sck);
3320
#endif
3321
  }
3322
  DBGLOG("net","[os_calls]->g_netlink_close() done.");
3323
}
3324
3325
/*****************************************************************************/
3326
int APP_CC
3327
g_netlink_bind(tbus sck) {
3328
#if defined(_WIN32)
3329
  return -1;
3330
#else
3331
  struct sockaddr_nl s;
3332
  //MDBGLOG("net","[os_calls]->g_netlink_bind() called: sck = %d; port = %s\0",sck,port);
3333
  g_memset(&s, 0, sizeof(struct sockaddr_nl));
3334
  s.nl_family = AF_NETLINK;
3335
  s.nl_groups = -1;
3336
  s.nl_pid = 0;
3337
  return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_nl));
3338
#endif
3339
}
3340
3341
#endif
3342
3343
/*****************************************************************************/
3344
/* produce a hex dump */
3345
void APP_CC
3346
g_hexdump_file(const char * f, char * p, size_t len) {
3347
3348
  unsigned char * line = (unsigned char *)NULL;
3349
  ptrdiff_t i = 0;
3350
  int thisline = 0;
3351
  ptrdiff_t offset = 0;
3352
  FILE * fp = (FILE *)NULL;
3353
3354
  fp = fopen(f,"a");
3355
  line = (unsigned char *)p;
3356
  offset = 0;
3357
  while (offset < len)
3358
  {
3359
    fprintf(fp, "%04x \t", offset);
3360
    thisline = len - offset;
3361
    if (thisline > 16)
3362
    {
3363
      thisline = 16;
3364
    }
3365
    for (i = 0; i < thisline; i++)
3366
    {
3367
      fprintf(fp,"%02x ", line[i]);
3368
    }
3369
    for (; i < 16; i++)
3370
    {
3371
      fprintf(fp,"   ");
3372
    }
3373
    for (i = 0; i < thisline; i++)
3374
    {
3375
      fprintf(fp,"%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
3376
    }
3377
    fprintf(fp, "\n");
3378
    offset += thisline;
3379
    line += thisline;
3380
  }
3381
  fclose(fp);
3382
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/os_calls.h (-92 / +215 lines)
 Lines 25-201    Link Here 
25
#if !defined(OS_CALLS_H)
25
#if !defined(OS_CALLS_H)
26
#define OS_CALLS_H
26
#define OS_CALLS_H
27
27
28
#include <sys/types.h>
29
#include <sys/time.h>
30
#include <sys/times.h>
31
#include <sys/wait.h>
32
#include <stddef.h>
33
#include <string.h>
34
#include <stdint.h>
35
#include <stdio.h>
28
#include "arch.h"
36
#include "arch.h"
29
37
38
  /*
39
   *	Define this constant (_XRDP_ENABLE_IPv6_) to 
40
   *	compile with IPv6 support:
41
   */
42
#define _XRDP_ENABLE_IPv6_
43
44
#define CHANSRV_USERNAME_PATH "/tmp/xrdp_chansrv_%8.8x_username"
45
#ifndef SELFPIPE_PATH
46
#define SELFPIPE_PATH   "/tmp/xrdp_chansrv_%8.8x_selfpipe"
47
#endif
48
#ifndef AUDIO_FIFO_PATH
49
#define AUDIO_FIFO_PATH   "/tmp/xrdp_audio_%d_fifo"
50
#endif
51
52
#ifndef NETLINK_CONNECTOR
53
#define NETLINK_CONNECTOR	11
54
#endif
55
30
void APP_CC
56
void APP_CC
31
g_init(void);
57
g_init(void);
32
void APP_CC
58
void APP_CC
33
g_deinit(void);
59
g_deinit(void);
34
void* APP_CC
60
void* APP_CC
35
g_malloc(int size, int zero);
61
g_malloc(int, int);
62
void * APP_CC
63
g_realloc(void *, int);
36
void APP_CC
64
void APP_CC
37
g_free(void* ptr);
65
g_free(void *);
66
void DEFAULT_CC
67
g_printf(const char *, ...);
38
void DEFAULT_CC
68
void DEFAULT_CC
39
g_printf(const char *format, ...);
69
g_sprintf(char *, const char *, ...);
40
void DEFAULT_CC
70
void DEFAULT_CC
41
g_sprintf(char* dest, const char* format, ...);
71
g_snprintf(char *, size_t, const char *, ...);
72
int DEFAULT_CC
73
g_scnprintf(char *, size_t, const char *, ...);
42
void DEFAULT_CC
74
void DEFAULT_CC
43
g_snprintf(char* dest, int len, const char* format, ...);
75
g_writeln(const char *, ...);
44
void DEFAULT_CC
76
void DEFAULT_CC
45
g_writeln(const char* format, ...);
77
g_write(const char *, ...);
46
void DEFAULT_CC
78
void DEFAULT_CC
47
g_write(const char* format, ...);
79
g_writeln_err(const char *, ...);
80
void DEFAULT_CC
81
g_write_err(const char *, ...);
82
void APP_CC
83
g_hexdump(const char *, size_t);
48
void APP_CC
84
void APP_CC
49
g_hexdump(char* p, int len);
85
g_hexdump_file(const char *, char *, size_t);
50
void APP_CC
86
void APP_CC
51
g_memset(void* ptr, int val, int size);
87
g_memset(void *, int, size_t);
52
void APP_CC
88
void APP_CC
53
g_memcpy(void* d_ptr, const void* s_ptr, int size);
89
g_memcpy(void *, const void *, size_t);
54
int APP_CC
90
int APP_CC
55
g_getchar(void);
91
g_getchar(void);
56
int APP_CC
92
int APP_CC
57
g_tcp_set_no_delay(int sck);
93
g_tcp_set_no_delay(tbus);
58
int APP_CC
94
int APP_CC
59
g_tcp_socket(void);
95
g_tcp_socket(void);
60
int APP_CC
96
int APP_CC
97
g_netlink_socket(void);
98
int APP_CC
61
g_tcp_local_socket(void);
99
g_tcp_local_socket(void);
100
int APP_CC
101
g_socketpair(int *);
62
void APP_CC
102
void APP_CC
63
g_tcp_close(int sck);
103
g_tcp_close(tbus);
104
void APP_CC
105
g_netlink_close(tbus);
106
int APP_CC
107
g_tcp_connect(tbus, const char *, const char *);
108
int APP_CC
109
g_tcp_local_connect(tbus, const char *);
64
int APP_CC
110
int APP_CC
65
g_tcp_connect(int sck, const char* address, const char* port);
111
g_tcp_force_send(tbus, const char *, size_t);
66
int APP_CC
112
int APP_CC
67
g_tcp_local_connect(int sck, const char* port);
113
g_tcp_force_recv(tbus, const char *, size_t);
68
int APP_CC
114
int APP_CC
69
g_tcp_force_send(int sck, char* data, int len);
115
g_tcp_set_non_blocking(tbus);
70
int APP_CC
116
int APP_CC
71
g_tcp_force_recv(int sck, char* data, int len);
117
g_tcp_set_blocking(tbus);
72
int APP_CC
118
int APP_CC
73
g_tcp_set_non_blocking(int sck);
119
g_fifo_set_blocking(tbus);
74
int APP_CC
120
int APP_CC
75
g_tcp_bind(int sck, char* port);
121
g_tcp_bind_flags(tbus, const char *, int);
76
int APP_CC
122
int APP_CC
77
g_tcp_local_bind(int sck, char* port);
123
g_tcp_bind(tbus, const char *);
78
int APP_CC
124
int APP_CC
79
g_tcp_listen(int sck);
125
g_netlink_bind(tbus);
80
int APP_CC
126
int APP_CC
81
g_tcp_accept(int sck);
127
g_tcp_local_bind(tbus, const char *);
82
int APP_CC
128
int APP_CC
83
g_tcp_recv(int sck, void* ptr, int len, int flags);
129
g_tcp_listen(tbus);
84
int APP_CC
130
int APP_CC
85
g_tcp_send(int sck, const void* ptr, int len, int flags);
131
g_tcp_accept(tbus);
132
size_t APP_CC
133
g_tcp_recv(tbus, void *, size_t, int);
134
size_t APP_CC
135
g_fifo_read(tbus, void *, size_t);
136
size_t APP_CC
137
g_fifo_write(tbus, const void *, size_t);
138
size_t APP_CC
139
g_tcp_send(tbus, const void *, size_t, int);
140
size_t APP_CC
141
g_tcp_send_force(tbus, const void *, size_t, int);
86
int APP_CC
142
int APP_CC
87
g_tcp_last_error_would_block(int sck);
143
g_tcp_last_error_would_block(tbus);
88
int APP_CC
144
int APP_CC
89
g_tcp_socket_ok(int sck);
145
g_tcp_socket_ok(tbus);
90
int APP_CC
146
int APP_CC
91
g_tcp_can_send(int sck, int millis);
147
g_tcp_can_send(tbus, int);
92
int APP_CC
148
int APP_CC
93
g_tcp_can_recv(int sck, int millis);
149
g_tcp_can_recv(tbus, int);
94
int APP_CC
150
int APP_CC
95
g_tcp_select(int sck1, int sck2);
151
g_fifo_can_read(tbus, int);
152
int APP_CC
153
g_tcp_select(tbus, tbus);
154
void APP_CC
155
g_sleep(uint64_t);
96
void APP_CC
156
void APP_CC
97
g_sleep(int msecs);
157
g_usleep(uint64_t);
158
tbus APP_CC
159
g_create_wait_obj(const char *);
160
tbus APP_CC
161
g_create_wait_obj_from_path(const char *);
98
tbus APP_CC
162
tbus APP_CC
99
g_create_wait_obj(char* name);
163
g_create_wait_obj_from_socket(tbus, int);
100
tbus APP_CC
164
tbus APP_CC
101
g_create_wait_obj_from_socket(tbus socket, int write);
165
g_create_wait_obj_from_fifo(tbus, int);
102
void APP_CC
166
void APP_CC
103
g_delete_wait_obj_from_socket(tbus wait_obj);
167
g_delete_wait_obj_from_socket(tbus);
104
int APP_CC
168
int APP_CC
105
g_set_wait_obj(tbus obj);
169
g_set_wait_obj(tbus);
106
int APP_CC
170
int APP_CC
107
g_reset_wait_obj(tbus obj);
171
g_reset_wait_obj(tbus);
108
int APP_CC
172
int APP_CC
109
g_is_wait_obj_set(tbus obj);
173
g_is_wait_obj_set(tbus);
110
int APP_CC
174
int APP_CC
111
g_delete_wait_obj(tbus obj);
175
g_delete_wait_obj(tbus);
112
int APP_CC
176
int APP_CC
113
g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount,
177
g_obj_wait(tbus *, int, tbus *, int, int);
114
           int mstimeout);
115
void APP_CC
178
void APP_CC
116
g_random(char* data, int len);
179
g_random(char *, int);
117
int APP_CC
180
int APP_CC
118
g_abs(int i);
181
g_abs(int);
119
int APP_CC
182
int APP_CC
120
g_memcmp(const void* s1, const void* s2, int len);
183
g_memcmp(const void *, const void *, size_t);
121
int APP_CC
184
int APP_CC
122
g_file_open(const char* file_name);
185
g_file_open(const char *);
123
int APP_CC
186
int APP_CC
124
g_file_close(int fd);
187
g_file_open_flags(const char *, int, mode_t);
188
void * APP_CC
189
g_shmalloc(size_t);
125
int APP_CC
190
int APP_CC
126
g_file_read(int fd, char* ptr, int len);
191
g_shfree(void *, size_t);
192
void * APP_CC
193
g_mmap(void *, size_t, int, int, int, off_t);
127
int APP_CC
194
int APP_CC
128
g_file_write(int fd, char* ptr, int len);
195
g_mkfifo(const char *, mode_t);
129
int APP_CC
196
int APP_CC
130
g_file_seek(int fd, int offset);
197
g_create_fifo(const char *);
131
int APP_CC
198
int APP_CC
132
g_file_lock(int fd, int start, int len);
199
g_fifo_open(const char *);
133
int APP_CC
200
int APP_CC
134
g_chmod_hex(const char* filename, int flags);
201
g_file_close(tbus);
202
ptrdiff_t APP_CC
203
g_file_read(tbus, char *, size_t);
204
ptrdiff_t APP_CC
205
g_file_write(tbus, const char *, size_t);
135
int APP_CC
206
int APP_CC
136
g_mkdir(const char* dirname);
207
g_file_seek(tbus, off_t);
137
char* APP_CC
138
g_get_current_dir(char* dirname, int maxlen);
139
int APP_CC
208
int APP_CC
140
g_set_current_dir(char* dirname);
209
g_file_lock(tbus, off_t, size_t);
141
int APP_CC
210
int APP_CC
142
g_file_exist(const char* filename);
211
g_chmod_hex(const char *, int);
143
int APP_CC
212
int APP_CC
144
g_directory_exist(const char* dirname);
213
g_mkdir(const char *);
214
char * APP_CC
215
g_get_current_dir(char *, size_t);
145
int APP_CC
216
int APP_CC
146
g_create_dir(const char* dirname);
217
g_set_current_dir(const char *);
147
int APP_CC
218
int APP_CC
148
g_remove_dir(const char* dirname);
219
g_file_exist(const char *);
149
int APP_CC
220
int APP_CC
150
g_file_delete(const char* filename);
221
g_directory_exist(const char *);
151
int APP_CC
222
int APP_CC
152
g_file_get_size(const char* filename);
223
g_create_dir(const char *);
153
int APP_CC
224
int APP_CC
154
g_strlen(const char* text);
225
g_remove_dir(const char *);
155
char* APP_CC
156
g_strcpy(char* dest, const char* src);
157
char* APP_CC
158
g_strncpy(char* dest, const char* src, int len);
159
char* APP_CC
160
g_strcat(char* dest, const char* src);
161
char* APP_CC
162
g_strdup(const char* in);
163
int APP_CC
226
int APP_CC
164
g_strcmp(const char* c1, const char* c2);
227
g_file_delete(const char *);
228
size_t APP_CC
229
g_file_get_size(const char *);
230
size_t APP_CC
231
g_strlen(const char *);
232
size_t APP_CC
233
g_strnlen(const char *, size_t);
234
char * APP_CC
235
g_strstr(const char *, const char *);
236
char * APP_CC
237
g_strchr(const char *, int);
238
char * APP_CC
239
g_strrchr(const char *, int);
240
char * APP_CC
241
g_strcpy(char *, const char *);
242
char * APP_CC
243
g_strncpy(char *, const char *, size_t);
244
char * APP_CC
245
g_strcat(char *, const char *);
246
char * APP_CC
247
g_strncat(char *, const char *, size_t);
248
char * APP_CC
249
g_strdup(const char *);
250
char * APP_CC
251
g_strndup(const char *, size_t);
252
/* char * APP_CC
253
g_strdup_printf  (const gchar *format, ...) G_GNUC_PRINTF (1, 2) G_GNUC_MALLOC; */
165
int APP_CC
254
int APP_CC
166
g_strncmp(const char* c1, const char* c2, int len);
255
g_strcmp(const char * c1, const char * c2);
167
int APP_CC
256
int APP_CC
168
g_strcasecmp(const char* c1, const char* c2);
257
g_strncmp(const char * c1, const char * c2, size_t len);
169
int APP_CC
258
int APP_CC
170
g_strncasecmp(const char* c1, const char* c2, int len);
259
g_strcasecmp(const char * c1, const char * c2);
171
int APP_CC
260
int APP_CC
172
g_atoi(char* str);
261
g_strncasecmp(const char * c1, const char * c2, size_t len);
173
int APP_CC
262
int APP_CC
174
g_htoi(char* str);
263
g_atoi(char * str);
175
int APP_CC
264
int APP_CC
176
g_pos(char* str, const char* to_find);
265
g_htoi(char * str);
177
int APP_CC
266
int APP_CC
178
g_mbstowcs(twchar* dest, const char* src, int n);
267
g_pos(char * str, const char * to_find);
179
int APP_CC
268
int APP_CC
180
g_wcstombs(char* dest, const twchar* src, int n);
269
g_mbstowcs(twchar * dest, const char * src, int n);
181
int APP_CC
270
int APP_CC
182
g_strtrim(char* str, int trim_flags);
271
g_wcstombs(char * dest, const twchar * src, int n);
272
int APP_CC
273
g_strtrim(char * str, int trim_flags);
183
long APP_CC
274
long APP_CC
184
g_load_library(char* in);
275
g_load_library(char * in);
185
int APP_CC
276
int APP_CC
186
g_free_library(long lib);
277
g_free_library(long lib);
187
void* APP_CC
278
void* APP_CC
188
g_get_proc_address(long lib, const char* name);
279
g_get_proc_address(long lib, const char * name);
189
int APP_CC
280
int APP_CC
190
g_system(char* aexec);
281
g_system(char * aexec);
191
char* APP_CC
282
char * APP_CC
192
g_get_strerror(void);
283
g_get_strerror(void);
193
int APP_CC
284
int APP_CC
194
g_get_errno(void);
285
g_get_errno(void);
195
int APP_CC
286
int APP_CC
196
g_execvp(const char* p1, char* args[]);
287
g_execvp(const char * p1, char * args[]);
197
int APP_CC
288
int APP_CC
198
g_execlp3(const char* a1, const char* a2, const char* a3);
289
g_execlp3(const char * a1, const char * a2, const char * a3);
199
void APP_CC
290
void APP_CC
200
g_signal_child_stop(void (*func)(int));
291
g_signal_child_stop(void (*func)(int));
201
void APP_CC
292
void APP_CC
 Lines 213-219    Link Here 
213
int APP_CC
304
int APP_CC
214
g_setgid(int pid);
305
g_setgid(int pid);
215
int APP_CC
306
int APP_CC
216
g_initgroups(const char* user, int gid);
307
g_initgroups(const char * user, int gid);
217
int APP_CC
308
int APP_CC
218
g_getuid(void);
309
g_getuid(void);
219
int APP_CC
310
int APP_CC
 Lines 225-251    Link Here 
225
void APP_CC
316
void APP_CC
226
g_clearenv(void);
317
g_clearenv(void);
227
int APP_CC
318
int APP_CC
228
g_setenv(const char* name, const char* value, int rewrite);
319
g_setenv(const char * name, const char * value, int rewrite);
229
char* APP_CC
320
char * APP_CC
230
g_getenv(const char* name);
321
g_getenv(const char * name);
231
int APP_CC
322
int APP_CC
232
g_exit(int exit_code);
323
g_exit(int exit_code);
233
int APP_CC
324
int APP_CC
234
g_getpid(void);
325
g_getpid(void);
235
int APP_CC
326
int APP_CC
327
g_gettid(void);
328
int APP_CC
236
g_sigterm(int pid);
329
g_sigterm(int pid);
237
int APP_CC
330
int APP_CC
238
g_getuser_info(const char* username, int* gid, int* uid, char* shell,
331
g_getuser_info(const char * username, int* gid, int* uid, char * shell,
239
               char* dir, char* gecos);
332
               char * dir, char * gecos);
240
int APP_CC
333
int APP_CC
241
g_getgroup_info(const char* groupname, int* gid);
334
g_getgroup_info(const char * groupname, int* gid);
242
int APP_CC
335
int APP_CC
243
g_check_user_in_group(const char* username, int gid, int* ok);
336
g_check_user_in_group(const char * username, int gid, int* ok);
244
int APP_CC
337
int APP_CC
245
g_time1(void);
338
g_time(time_t *);
246
int APP_CC
339
int APP_CC
340
g_time1(void);
341
long int APP_CC
247
g_time2(void);
342
g_time2(void);
248
int APP_CC
343
int APP_CC
249
g_time3(void);
344
g_time3(void);
345
char ** APP_CC
346
g_dir_list_contents(const char * dirname, char ** contents, int * count);
347
int APP_CC
348
g_dir_create(const char * dirname, int flags);
349
int APP_CC
350
timeval_subtract (struct timeval *, struct timeval *, struct timeval *);
351
struct timeval APP_CC
352
mk_timeval(int, int);
353
struct timeval * APP_CC
354
timeval_round(struct timeval *);
355
double APP_CC
356
timeval_to_double(const struct timeval *);
357
struct timeval APP_CC
358
double_to_timeval(const double *);
359
360
/* string encoding conversion functions: */
361
int APP_CC g_iconv_init();
362
int APP_CC g_iconv_end();
363
int APP_CC g_instr(char **, int *, char **, int *);
364
int APP_CC g_outstr(char **, int *, char **, int *);
365
366
char * APP_CC g_strsep(char **, const char *);
367
368
#define EPOCH_DIFF 0x019DB1DED53E8000LL /* 116444736000000000 nsecs */
369
#define RATE_DIFF 10000000 /* 100 nsecs */
370
typedef int64_t filetime_t;
371
filetime_t UnixToFileTime(time_t);
372
time_t FileTimeToUnix(filetime_t);
250
373
251
#endif
374
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/parse.h (+196 lines)
 Lines 29-34    Link Here 
29
#if !defined(PARSE_H)
29
#if !defined(PARSE_H)
30
#define PARSE_H
30
#define PARSE_H
31
31
32
#include <stdint.h>
32
#include "arch.h"
33
#include "arch.h"
33
34
34
#if defined(L_ENDIAN)
35
#if defined(L_ENDIAN)
 Lines 37-42    Link Here 
37
#error Unknown endianness.
38
#error Unknown endianness.
38
#endif
39
#endif
39
40
41
#define NEED_ALIGN
42
40
/* parser state */
43
/* parser state */
41
struct stream
44
struct stream
42
{
45
{
 Lines 112-117    Link Here 
112
}
115
}
113
116
114
/******************************************************************************/
117
/******************************************************************************/
118
#define s_get_pos(s) \
119
  ((void *)((s)->p))
120
121
/******************************************************************************/
122
#define s_size(s) (size_t)((s)->end - (s)->data)
123
124
/******************************************************************************/
125
#define s_current_size(s) (size_t)((s)->p - (s)->data)
126
127
/******************************************************************************/
128
#define s_crc32(s)     (uint32_t)(((s)->data != NULL && (s)->end != NULL && (s)->end > (s)->data) ? Crc32_ComputeBuf(0, (s)->data, s_size(s)) : 0)
129
130
/******************************************************************************/
115
#define in_sint8(s, v) \
131
#define in_sint8(s, v) \
116
{ \
132
{ \
117
  (v) = *((signed char*)((s)->p)); \
133
  (v) = *((signed char*)((s)->p)); \
 Lines 211-216    Link Here 
211
}
227
}
212
228
213
/******************************************************************************/
229
/******************************************************************************/
230
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
231
#define in_int32_le(s, v) \
232
{ \
233
  (v) = (int) \
234
    ( \
235
      (*((unsigned char*)((s)->p + 0)) << 0) | \
236
      (*((unsigned char*)((s)->p + 1)) << 8) | \
237
      (*((unsigned char*)((s)->p + 2)) << 16) | \
238
      (*((unsigned char*)((s)->p + 3)) << 24) \
239
    ); \
240
  (s)->p += 4; \
241
}
242
#else
243
#define in_int32_le(s, v) \
244
{ \
245
  (v) = *((int*)((s)->p)); \
246
  (s)->p += 4; \
247
}
248
#endif
249
250
#define in_sint32_le(s, v)	in_int32_le(s, v)
251
252
/******************************************************************************/
253
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
254
#define in_uint64_le(s, v) \
255
{ \
256
  (v) = (unsigned long long) \
257
    ( \
258
      (*((unsigned char*)((s)->p + 0)) << 0) | \
259
      (*((unsigned char*)((s)->p + 1)) << 8) | \
260
      (*((unsigned char*)((s)->p + 2)) << 16) | \
261
      (*((unsigned char*)((s)->p + 3)) << 24) | \
262
      ((unsigned long long)(*((unsigned char*)((s)->p + 4))) << 32) | \
263
      ((unsigned long long)(*((unsigned char*)((s)->p + 5))) << 40) | \
264
      ((unsigned long long)(*((unsigned char*)((s)->p + 6))) << 48) | \
265
      ((unsigned long long)(*((unsigned char*)((s)->p + 7))) << 56) \
266
    ); \
267
  (s)->p += 8; \
268
}
269
#else
270
#define in_uint64_le(s, v) \
271
{ \
272
  (v) = *((unsigned long long*)((s)->p)); \
273
  (s)->p += 8; \
274
}
275
#endif
276
277
/******************************************************************************/
278
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
279
#define in_int64_le(s, v) \
280
{ \
281
  (v) = (unsigned long long) \
282
    ( \
283
      (*((unsigned char*)((s)->p + 0)) << 0) | \
284
      (*((unsigned char*)((s)->p + 1)) << 8) | \
285
      (*((unsigned char*)((s)->p + 2)) << 16) | \
286
      (*((unsigned char*)((s)->p + 3)) << 24) | \
287
      ((unsigned long long)(*((unsigned char*)((s)->p + 4))) << 32) | \
288
      ((unsigned long long)(*((unsigned char*)((s)->p + 5))) << 40) | \
289
      ((unsigned long long)(*((unsigned char*)((s)->p + 6))) << 48) | \
290
      ((unsigned long long)(*((unsigned char*)((s)->p + 7))) << 56) \
291
    ); \
292
  (s)->p += 8; \
293
}
294
#else
295
#define in_int64_le(s, v) \
296
{ \
297
  (v) = *((unsigned long long*)((s)->p)); \
298
  (s)->p += 8; \
299
}
300
#endif
301
302
/******************************************************************************/
303
#define in_uint64_be(s, v) \
304
{ \
305
  (v) = *((unsigned char*)((s)->p)); \
306
  (s)->p++; \
307
  (v) <<= 8; \
308
  (v) |= *((unsigned char*)((s)->p)); \
309
  (s)->p++; \
310
  (v) <<= 8; \
311
  (v) |= *((unsigned char*)((s)->p)); \
312
  (s)->p++; \
313
  (v) <<= 8; \
314
  (v) |= *((unsigned char*)((s)->p)); \
315
  (s)->p++; \
316
  (v) <<= 8; \
317
  (v) |= *((unsigned char*)((s)->p)); \
318
  (s)->p++; \
319
  (v) <<= 8; \
320
  (v) |= *((unsigned char*)((s)->p)); \
321
  (s)->p++; \
322
  (v) <<= 8; \
323
  (v) |= *((unsigned char*)((s)->p)); \
324
  (s)->p++; \
325
  (v) <<= 8; \
326
  (v) |= *((unsigned char*)((s)->p)); \
327
  (s)->p++; \
328
}
329
330
/******************************************************************************/
214
#define out_uint8(s, v) \
331
#define out_uint8(s, v) \
215
{ \
332
{ \
216
  *((s)->p) = (unsigned char)(v); \
333
  *((s)->p) = (unsigned char)(v); \
 Lines 278-283    Link Here 
278
}
395
}
279
396
280
/******************************************************************************/
397
/******************************************************************************/
398
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
399
#define out_uint64_le(s, v) \
400
{ \
401
  *((s)->p) = (unsigned char)((v) >> 0); \
402
  (s)->p++; \
403
  *((s)->p) = (unsigned char)((v) >> 8); \
404
  (s)->p++; \
405
  *((s)->p) = (unsigned char)((v) >> 16); \
406
  (s)->p++; \
407
  *((s)->p) = (unsigned char)((v) >> 24); \
408
  (s)->p++; \
409
  *((s)->p) = (unsigned char)((v) >> 32); \
410
  (s)->p++; \
411
  *((s)->p) = (unsigned char)((v) >> 40); \
412
  (s)->p++; \
413
  *((s)->p) = (unsigned char)((v) >> 48); \
414
  (s)->p++; \
415
  *((s)->p) = (unsigned char)((v) >> 56); \
416
  (s)->p++; \
417
}
418
#else
419
#define out_uint64_le(s, v) \
420
{ \
421
  *((unsigned long long*)((s)->p)) = (v); \
422
  (s)->p += 8; \
423
}
424
#endif
425
426
/******************************************************************************/
427
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
428
#define out_int64_le(s, v) \
429
{ \
430
  *((s)->p) = (unsigned char)((v) >> 0); \
431
  (s)->p++; \
432
  *((s)->p) = (unsigned char)((v) >> 8); \
433
  (s)->p++; \
434
  *((s)->p) = (unsigned char)((v) >> 16); \
435
  (s)->p++; \
436
  *((s)->p) = (unsigned char)((v) >> 24); \
437
  (s)->p++; \
438
  *((s)->p) = (unsigned char)((v) >> 32); \
439
  (s)->p++; \
440
  *((s)->p) = (unsigned char)((v) >> 40); \
441
  (s)->p++; \
442
  *((s)->p) = (unsigned char)((v) >> 48); \
443
  (s)->p++; \
444
  *((s)->p) = (unsigned char)((v) >> 56); \
445
  (s)->p++; \
446
}
447
#else
448
#define out_int64_le(s, v) \
449
{ \
450
  *((unsigned long long*)((s)->p)) = (v); \
451
  (s)->p += 8; \
452
}
453
#endif
454
455
/******************************************************************************/
456
#define out_uint64_be(s, v) \
457
{ \
458
  *((s)->p) = (unsigned char)((v) >> 56); \
459
  s->p++; \
460
  *((s)->p) = (unsigned char)((v) >> 48); \
461
  s->p++; \
462
  *((s)->p) = (unsigned char)((v) >> 40); \
463
  s->p++; \
464
  *((s)->p) = (unsigned char)((v) >> 32); \
465
  s->p++; \
466
  *((s)->p) = (unsigned char)((v) >> 24); \
467
  s->p++; \
468
  *((s)->p) = (unsigned char)((v) >> 16); \
469
  s->p++; \
470
  *((s)->p) = (unsigned char)((v) >> 8); \
471
  s->p++; \
472
  *((s)->p) = (unsigned char)(v); \
473
  (s)->p++; \
474
}
475
476
/******************************************************************************/
281
#define in_uint8p(s, v, n) \
477
#define in_uint8p(s, v, n) \
282
{ \
478
{ \
283
  (v) = (s)->p; \
479
  (v) = (s)->p; \
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/rdpdr.h (+574 lines)
Line 0    Link Here 
1
#ifndef FUSE_USE_VERSION
2
#define FUSE_USE_VERSION 26
3
#endif
4
5
#ifndef __XRDP_RDPDR_DEF__
6
#define __XRDP_RDPDR_DEF__
7
8
#include <assert.h>
9
#include <stddef.h>
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <unistd.h>
13
#include <fcntl.h>
14
#include <string.h>
15
#include <stdint.h>
16
#include <errno.h>
17
#include <semaphore.h>
18
#include <pthread.h>
19
#include <netdb.h>
20
#include <signal.h>
21
#include <sys/un.h>
22
#include <sys/uio.h>
23
#include <sys/types.h>
24
#include <sys/time.h>
25
#include <sys/wait.h>
26
#include <sys/utsname.h>
27
#include <sys/mman.h>
28
#include <sys/poll.h>
29
#include <fuse/fuse_lowlevel.h>
30
#include <fuse.h>
31
#include <netinet/in.h>
32
#include <netinet/tcp.h>
33
34
#include "thread_calls.h"
35
36
#include "devredir_defs.h"
37
#include "drdynvc_defs.h"
38
#include "recording_defs.h"
39
40
#define htobel(x)	(htonl(x))
41
42
struct buffer;
43
struct request;
44
struct list_head;
45
struct read_chunk;
46
struct _rdpfs_file;
47
struct _rdpfs;
48
struct _rdpport;
49
struct _rdpprint;
50
struct _rdpsc;
51
52
typedef struct _filelist_entry {
53
	int			index;
54
	char			filename[512];
55
	uint64_t		CreationTime;
56
	uint64_t		LastAccessTime;
57
	uint64_t		LastWriteTime;
58
	uint64_t		ChangeTime;
59
	uint64_t		EndOfFile;
60
	uint64_t		AllocationSize;
61
	uint32_t		FileAttributes;
62
	uint32_t		NumberOfLinks;
63
	uint8_t			DeletePending;
64
	uint8_t			Directory;
65
	uint32_t		EaSize;
66
} filelist_entry;
67
68
typedef struct _filelist {
69
  #ifndef FILELIST_MAX
70
  #define FILELIST_MAX 4096
71
  #endif
72
  int				count;
73
  filelist_entry *		files[FILELIST_MAX];
74
} filelist;
75
76
typedef struct buffer {
77
	uint8_t *p;
78
	size_t len;
79
	size_t size;
80
} rdpfs_buffer;
81
82
typedef struct list_head {
83
	struct list_head * prev;
84
	struct list_head * next;
85
} rdpfs_list_head;
86
87
typedef void (*request_func)(struct request *);
88
89
typedef struct request {
90
	unsigned int want_reply;
91
	sem_t ready;
92
	uint8_t reply_type;
93
	int replied;
94
	int error;
95
	struct buffer reply;
96
	struct timeval start;
97
	void *data;
98
	request_func end_func;
99
	size_t len;
100
	struct list_head list;
101
} rdpfs_req;
102
103
typedef struct _read_chunk {
104
	sem_t ready;
105
	off_t offset;
106
	size_t size;
107
	struct buffer data;
108
	int refs;
109
	int res;
110
	long modifver;
111
} read_chunk;
112
113
typedef struct _rdpfs_file {
114
	struct buffer handle;
115
	struct list_head write_reqs;
116
	pthread_cond_t write_finished;
117
	int write_error;
118
	struct read_chunk * readahead;
119
	off_t next_pos;
120
	int is_seq;
121
	int connver;
122
	int modifver;
123
	int refs;
124
} rdpfs_file;
125
126
#ifndef _FUSE_LOWLEVEL_H_
127
struct fuse_chan_ops {
128
	int(*receive )(struct fuse_chan **chp, char *buf, size_t size);
129
	int(*send )(struct fuse_chan *ch, const struct iovec iov[], size_t count);
130
	void(*destroy )(struct fuse_chan *ch);
131
};
132
#endif
133
134
struct fuse_chan {
135
	struct fuse_chan_ops op;
136
	struct fuse_session *se;
137
	int fd;
138
	size_t bufsize;
139
	void *data;
140
	int compat;
141
};
142
143
typedef struct _rdpfs_data {
144
	int callback_index;
145
	int FileId;
146
	int length;
147
	void * data;
148
} rdpfs_data, rdpport_data, rdpprint_data, rdpsc_data;
149
150
struct _callback;
151
152
#ifndef __RDPFS_STATE__
153
#define __RDPFS_STATE__
154
struct rdpfs_state {
155
    FILE * logfile;
156
    char * rootdir;
157
};
158
159
#define RDPFS_DATA ((struct rdpfs_state *) fuse_get_context()->private_data)
160
161
//#define RDPFS_DATA ((struct rdpfs_state *) ((fuse_get_context() == NULL) ? NULL : fuse_get_context()->private_data)))
162
#endif
163
164
typedef struct _rdpfs {
165
166
    #ifndef MAX_PENDING
167
//    #define MAX_PENDING	512
168
    #define MAX_PENDING		25
169
    #endif
170
    #ifndef MAX_REQID
171
    #define MAX_REQID		25
172
    #endif
173
    #define ANY_FS		0x00000100
174
    #define RDP_FS		0x00000100
175
    #define RDPFS_CONTEXT_MAGIC	0xdadee777
176
177
	FILE *						logfile;
178
	char *						rootdir;
179
	uint32_t					magic;
180
	uint32_t					device_id;
181
	int						type;		/*	0x00000100 = RDPFS	 */
182
	int						fd;
183
	struct trans *					ccon;
184
	int						handler_pid;
185
	int						parent_pid;
186
	int						child_pid;
187
	int						parent_sck;
188
	int						child_sck;
189
	int						top_opid;
190
	int						pending_opids[MAX_PENDING];
191
//	struct _callback *				callbacks[MAX_PENDING];
192
//	struct _callback *				callbacks;
193
//	struct _callback **				callbacks;
194
	struct _callback				callbacks[MAX_PENDING];
195
	struct _rdpfs *					g_fs;
196
	int						g_device_index;
197
	int						g_fs_index;
198
	int						connver;
199
	int						server_version;
200
	int						debug;
201
	tc_t						mut;
202
	tc_t						mut_write;
203
	unsigned char					processing_thread_started;
204
	int						fhandle;
205
	char *						mountpoint;
206
	char *						dos_name;
207
	struct fuse *					fuse;
208
	struct fuse_chan *				ch;
209
	struct fuse_args				rdpfs_args;
210
	int						transform_symlinks;
211
	int						detect_uid;
212
	unsigned int					max_read;
213
	unsigned int					max_write;
214
	int						sync_write;
215
	int						sync_read;
216
	int						foreground;
217
	int						reconnect;
218
	char *						host;
219
	char *						base_path;
220
	unsigned int					randseed;
221
	unsigned int					remote_uid;
222
	unsigned int					local_uid;
223
	int						remote_uid_detected;
224
	unsigned int					blksize;
225
	char *						progname;
226
	int						ext_posix_rename;
227
	int						ext_statvfs;
228
	mode_t						mnt_mode;
229
	unsigned char					initialized;
230
231
	/* statistics */
232
	uint64_t bytes_sent;
233
	uint64_t bytes_received;
234
	uint64_t num_sent;
235
	uint64_t num_received;
236
	unsigned int min_rtt;
237
	unsigned int max_rtt;
238
	uint64_t total_rtt;
239
	unsigned int num_connect;
240
241
	/* locking */
242
	tc_t						g_cv_readdir;
243
244
	tc_t						g_mutex_pcon_fs;
245
	tc_t						g_mutex_fs;
246
	tc_t						g_mutex_parent_fs;
247
	tc_t						g_mutex_fuse;
248
	tc_t						g_mutex_fsop;
249
	tc_t						g_mutex_reqid_fs;
250
	tc_t						g_mutex_getattr;
251
252
	tc_p						cv_readdir;
253
	tc_p						mutex_pcon_fs;
254
	tc_p						mutex_fs;
255
	tc_p						mutex_parent_fs;
256
	tc_p						mutex_fuse;
257
	tc_p						mutex_fsop;
258
	tc_p						mutex_reqid_fs;
259
	tc_p						mutex_getattr;
260
261
} rdpfs, rdpfs_t, rdpfs_context_t;
262
263
#define RDPFS_DECS	rdpfs * g_fs __attribute__ ((unused)) = (rdpfs *)RDPFS_DATA;			\
264
			int g_fd __attribute__ ((unused)) = g_fs->fd;					\
265
			callback * g_reqids __attribute__ ((unused)) = (callback *)(g_fs->callbacks);	\
266
			uint32_t device_id __attribute__ ((unused)) = 0;
267
268
269
typedef struct _rdpport {
270
	#define ANY_PORT	0x00000200
271
	#define SERIAL_PORT	0x00000201
272
	#define PARALLEL_PORT	0x00000202
273
	uint32_t device_id;
274
	int type;		/*	0x00000201 = serial; 0x00000202 = parallel	*/
275
	int fd;
276
	struct trans * ccon;
277
	int handler_pid;
278
	int parent_pid;
279
	int child_pid;
280
	int parent_sck;
281
	int child_sck;
282
	int top_opid;
283
	int pending_opids[MAX_PENDING];
284
	struct _callback * callbacks[MAX_PENDING];
285
	struct _rdpport * g_port;
286
	int g_device_index;
287
	int g_port_index;
288
	int connver;
289
	int server_version;
290
	int debug;
291
	pthread_mutex_t lock;
292
	pthread_mutex_t lock_write;
293
	int processing_thread_started;
294
	int fhandle;		/* the file descriptor corresponding to the opened serial/parallel port */
295
	char * file_path;
296
	char * dos_name;
297
} rdpport_t;
298
299
typedef struct _rdpprint {
300
	#define ANY_PRINTER		0x00000400
301
	#define NORMAL_PRINTER		0x00000401
302
	#define	XPS_PRINTER		0x00000402
303
	uint32_t device_id;
304
	int type;		/*	0x00000401 = normal; 0x00000402 = xps	*/
305
	int fd;
306
	struct trans * ccon;
307
	int handler_pid;
308
	int parent_pid;
309
	int child_pid;
310
	int parent_sck;
311
	int child_sck;
312
	int top_opid;
313
	int pending_opids[MAX_PENDING];
314
	struct _callback * callbacks[MAX_PENDING];
315
	struct _rdpprint * g_printer;
316
	int g_device_index;
317
	int g_printer_index;
318
	int connver;
319
	int server_version;
320
	int debug;
321
	pthread_mutex_t lock;
322
	pthread_mutex_t lock_write;
323
	int processing_thread_started;
324
	int fhandle;		/* the file descriptor corresponding to the opened printer */
325
	char * file_path;
326
	char * dos_name;
327
} rdpprint;
328
329
typedef struct _rdpsc {
330
	#define RDP_SC			0x00000800
331
	uint32_t device_id;
332
	int type;		/*	0x00000800 = RDP smartcard	*/
333
	int fd;
334
	struct trans * ccon;
335
	int handler_pid;
336
	int parent_pid;
337
	int child_pid;
338
	int parent_sck;
339
	int child_sck;
340
	int top_opid;
341
	int pending_opids[MAX_PENDING];
342
	struct _callback * callbacks[MAX_PENDING];
343
	struct _rdpport * g_sc;
344
	int g_device_index;
345
	int g_smartcard_index;
346
	int connver;
347
	int server_version;
348
	int debug;
349
	pthread_mutex_t lock;
350
	pthread_mutex_t lock_write;
351
	int processing_thread_started;
352
	int fhandle;		/* the file descriptor corresponding to the opened smart card */
353
	char * file_path;
354
	char * dos_name;
355
} rdpsc;
356
357
typedef union _rdpdevicetypes {
358
	rdpfs		fs;
359
	rdpport_t	port;
360
	rdpprint	printer;
361
	rdpsc		smartcard;
362
} rdpdev;
363
364
enum  {
365
    KEY_HELP,
366
    KEY_HELP_NOHEADER,
367
    KEY_VERSION,
368
    KEY_KEEP,
369
};
370
371
struct helper_opts {
372
    int singlethread;
373
    int foreground;
374
    int fsname;
375
    char *mountpoint;
376
};
377
378
#define FUSE_HELPER_OPT(t, p) { t, offsetof(struct helper_opts, p), 1 }
379
380
/* Function signatures: */
381
382
unsigned long rdpfs_hash(unsigned char *);
383
384
#define RDP_ERROR		0x01000000
385
#define RDP_REPLY		0x08000000
386
#define RDP_INIT		0x0000100F
387
#define RDP_OPEN		0x00001000
388
#define RDP_CLOSE		0x00002000
389
#define RDP_READ		0x00004000
390
#define RDP_WRITE		0x00008000
391
#define RDP_IOCTL		0x00008D01
392
393
/* devredir <--> fs_handler opcodes */
394
#define RDPFS_NEGOTIATE		0x00100000
395
#define RDPFS_LOOKUP		0x00100001
396
#define RDPFS_FORGET		0x00100002
397
#define RDPFS_READLINK		0x001040F0
398
#define RDPFS_GETATTR		0x00104D00
399
#define RDPFS_SETATTR		0x00108D00
400
#define RDPFS_MKNOD		0x00100005
401
#define RDPFS_MKDIR		0x00100008
402
#define RDPFS_UNLINK		0x001080A0
403
#define RDPFS_RELEASE		0x00102000
404
#define RDPFS_RMDIR		0x001080A1
405
#define RDPFS_SYMLINK		0x00101140
406
#define RDPFS_RENAME		0x001081A0
407
#define RDPFS_LINK		0x00101180
408
#define RDPFS_CHMOD		0x00108200
409
#define RDPFS_CHOWN		0x00108210
410
#define RDPFS_TRUNCATE		0x00108400
411
#define RDPFS_UTIME		0x00108800
412
#define RDPFS_OPEN		0x00101000
413
#define RDPFS_READ		0x00104000
414
#define RDPFS_WRITE		0x00108000
415
#define RDPFS_STATFS		0x00104002
416
#define RDPFS_FLUSH		0x00108080
417
#define RDPFS_FSYNC		0x00108B40
418
#define RDPFS_GETXATTR		0x00104F00
419
#define RDPFS_SETXATTR		0x00108F00
420
#define RDPFS_LISTXATTR		0x00104F10
421
#define RDPFS_REMOVEXATTR	0x00108FA0
422
#define RDPFS_OPENDIR		0x00101001
423
#define RDPFS_READDIR		0x00104001
424
#define RDPFS_RELEASEDIR	0x00102001
425
#define RDPFS_FSYNCDIR		0x00108B41
426
#define RDPFS_INIT		0x0010100F
427
#define RDPFS_DESTROY		0x0010200F
428
#define RDPFS_ACCESS		0x00104E00
429
#define RDPFS_CREATE		0x00101110
430
#define RDPFS_FTRUNCATE		0x00108440
431
#define RDPFS_FGETATTR		0x00104D40
432
#define RDPFS_IOCTL		0x00108D01
433
#define RDPFS_BMAP		0x00104202
434
#define RDPFS_POLL		0x00104303
435
#define RDPFS_FSCTL		0x00108C02
436
#define RDPFS_END		0x0010200E
437
#define RDPFS_ERROR		0x01000000
438
#define RDPFS_REPLY		0x08000000
439
440
#define RDPPORT_INIT		0x0001100F
441
#define RDPPORT_OPEN		0x00011000
442
#define RDPPORT_READ		0x00014000
443
#define RDPPORT_WRITE		0x00018000
444
#define RDPPORT_CLOSE		0x00012000
445
#define RDPPORT_IOCTL		0x00018D01
446
#define RDPPORT_DESTROY		0x0001200F
447
#define RDPPORT_ERROR		0x01000000
448
#define RDPPORT_REPLY		0x08000000
449
#define RDPPORT_END		0x0001200E
450
451
#define RDPPRINT_INIT		0x0002100F
452
#define RDPPRINT_OPEN		0x00021000
453
#define RDPPRINT_READ		0x00024000
454
#define RDPPRINT_WRITE		0x00028000
455
#define RDPPRINT_CLOSE		0x00022000
456
#define RDPPRINT_IOCTL		0x00028D01
457
#define RDPPRINT_DESTROY	0x0002200F
458
#define RDPPRINT_ERROR		0x01000000
459
#define RDPPRINT_REPLY		0x08000000
460
#define RDPPRINT_END		0x0002200E
461
462
#define RDPSC_INIT		0x0008100F
463
#define RDPSC_OPEN		0x00081000
464
#define RDPSC_READ		0x00084000
465
#define RDPSC_WRITE		0x00088000
466
#define RDPSC_CLOSE		0x00082000
467
#define RDPSC_IOCTL		0x00088D01
468
#define RDPSC_DESTROY		0x0008200F
469
#define RDPSC_ERROR		0x01000000
470
#define RDPSC_REPLY		0x08000000
471
#define RDPSC_END		0x0008200E
472
473
474
enum rdp_message_types {
475
	RDP_M_PING = 0x00,
476
	RDP_M_IOCTL = 0x01,
477
	RDP_M_SETMCTRL = 0x02,
478
	RDP_M_GETMCTRL = 0x03,
479
	RDP_M_GETSTATUS = 0x04,
480
	RDP_M_ADDPORT = 0x05,
481
	RDP_M_OPEN = 0x06,
482
	RDP_M_CLOSE = 0x07,
483
	RDP_M_READ = 0x08,
484
	RDP_M_WRITE = 0x09,
485
	RDP_M_DATA = 0x0A,
486
	RDP_M_START = 0x0B,
487
	RDP_M_STOP = 0x0C,
488
	RDP_M_GETBAUD = 0x0D,
489
	RDP_M_SETBAUD = 0x0E,
490
	RDP_M_TXEMPTY = 0x0F,
491
	RDP_M_TXFULL = 0x10,
492
	RDP_M_TXSTOP = 0x11,
493
	RDP_M_TXSTART = 0x12,
494
	RDP_M_RXEMPTY = 0x13,
495
	RDP_M_RXFULL = 0x14,
496
	RDP_M_RXSTOP = 0x15,
497
	RDP_M_RXSTART = 0x16,
498
	RDP_M_MSENABLE = 0x17,
499
	RDP_M_BREAKCTL = 0x18,
500
	RDP_M_SETTERMIOS = 0x19,
501
	RDP_M_GETTERMIOS = 0x1A,
502
	RDP_M_XCHAR = 0x1B,
503
	RDP_M_ASYNC = 0x40,
504
	RDP_M_REPLY = 0x80,
505
};
506
507
#define CMD_TO_STRING_ARRAY_DEF { \
508
	[0x00] = "RDP_M_PING", \
509
	[0x01] = "RDP_M_IOCTL", \
510
	[0x02] = "RDP_M_SETMCTRL", \
511
	[0x03] = "RDP_M_GETMCTRL", \
512
	[0x04] = "RDP_M_GETSTATUS", \
513
	[0x05] = "RDP_M_ADDPORT", \
514
	[0x06] = "RDP_M_OPEN", \
515
	[0x07] = "RDP_M_CLOSE", \
516
	[0x08] = "RDP_M_READ", \
517
	[0x09] = "RDP_M_WRITE", \
518
	[0x0A] = "RDP_M_DATA", \
519
	[0x0B] = "RDP_M_START", \
520
	[0x0C] = "RDP_M_STOP", \
521
	[0x0D] = "RDP_M_GETBAUD", \
522
	[0x0E] = "RDP_M_SETBAUD", \
523
	[0x0F] = "RDP_M_TXEMPTY", \
524
	[0x10] = "RDP_M_TXFULL", \
525
	[0x11] = "RDP_M_TXSTOP", \
526
	[0x12] = "RDP_M_TXSTART", \
527
	[0x13] = "RDP_M_RXEMPTY", \
528
	[0x14] = "RDP_M_RXFULL", \
529
	[0x15] = "RDP_M_RXSTOP", \
530
	[0x16] = "RDP_M_RXSTART", \
531
	[0x17] = "RDP_M_MSENABLE", \
532
	[0x18] = "RDP_M_BREAKCTL", \
533
	[0x19] = "RDP_M_SETTERMIOS", \
534
	[0x1A] = "RDP_M_GETTERMIOS", \
535
	[0x1B] = "RDP_M_XCHAR", \
536
	[0x40] = "RDP_M_ASYNC", \
537
	[0x80] = "RDP_M_REPLY", \
538
}
539
540
#define RDP_PACKET_MAGIC	0xfeeddeef
541
542
typedef struct rdpfs_shm {
543
	DR_DEVICELIST_ANNOUNCE_STATIC		client_devicelist;
544
	DEVICE_ANNOUNCE	*			DeviceList_arr[96];
545
	struct _rdpfs *				fs_arr[24];
546
	struct _rdpfs				fs_arr_s[24];
547
	rdpport_t *				port_arr[24];
548
	rdpport_t				port_arr_s[24];
549
	rdpprint *				print_arr[24];
550
	rdpprint				print_arr_s[24];
551
	rdpsc *					sc_arr[24];
552
	rdpsc					sc_arr_s[24];
553
} rdpfs_shm_t, * rdpfs_shm_p;
554
555
typedef struct rdpfs_shm_blob {
556
	uint32_t				len;
557
	rdpfs_shm_t				shm;
558
} rdpfs_shm_blob_t;
559
560
void * g_shm;
561
size_t * g_shm_len;
562
int * g_shm_sem;
563
564
tc_p            mutex_client_devicelist;
565
/*
566
tc_p            mutex_fs_arr;
567
tc_p            mutex_port_arr;
568
tc_p            mutex_printer_arr;
569
tc_p            mutex_smartcard_arr;
570
*/
571
572
573
574
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/rdpdr_methods.c (+4928 lines)
Line 0    Link Here 
1
2
#include "os_calls.h"
3
#include "rdpdr.h"
4
#include "rdpdr_methods.h"
5
#include "parse.h"
6
7
8
/**********************************************************************
9
 *		static declarations
10
 **********************************************************************/
11
12
static int APP_CC setPath_DR_DRIVE_QUERY_DIRECTORY_REQ(struct _DR_DRIVE_QUERY_DIRECTORY_REQ *, const char *);
13
14
15
/**********************************************************************
16
 *		global variables
17
 **********************************************************************/
18
19
20
/**********************************************************************
21
 *		BEGIN:	CONSTRUCTORS
22
 **********************************************************************/
23
24
int APP_CC construct_RDPDR_HEADER(RDPDR_HEADER * self) {
25
  int rv = 0;
26
27
  g_memset(self,0,sizeof(RDPDR_HEADER));
28
  self->Component = RDPDR_CTYP_CORE;
29
  self->out = &send_RDPDR_HEADER;
30
  self->in = &get_RDPDR_HEADER;
31
32
  return rv;
33
}
34
35
int APP_CC construct_CAPABILITY_HEADER(CAPABILITY_HEADER * self) {
36
  int rv = 0;
37
38
  g_memset(self,0,sizeof(CAPABILITY_HEADER));
39
  self->out = &send_CAPABILITY_HEADER;
40
  self->in = &get_CAPABILITY_HEADER;
41
42
  return rv;
43
}
44
45
int APP_CC construct_CAPABILITY_SET(CAPABILITY_SET * self) {
46
  int rv = 0;
47
48
  g_memset(self,0,sizeof(CAPABILITY_SET));
49
  self->out = &send_CAPABILITY_SET;
50
  self->in = &get_CAPABILITY_SET;
51
52
  return rv;
53
}
54
55
int APP_CC construct_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE * self) {
56
  int rv = 0;
57
58
  g_memset(self,0,sizeof(DEVICE_ANNOUNCE));
59
  self->out = &send_DEVICE_ANNOUNCE;
60
  self->in = &get_DEVICE_ANNOUNCE;
61
62
  return rv;
63
}
64
65
int APP_CC construct_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST * self) {
66
  int rv = 0;
67
68
  g_memset(self,0,sizeof(DR_DEVICE_IOREQUEST));
69
  construct_RDPDR_HEADER(&(self->Header));
70
  self->Header.Component = RDPDR_CTYP_CORE;
71
  self->Header.PacketId = PAKID_CORE_DEVICE_IOREQUEST;
72
  self->Header.out = &send_RDPDR_HEADER;
73
  self->Header.in = &get_RDPDR_HEADER;
74
  self->Header.__destructor = NULL;
75
  self->out = &send_DR_DEVICE_IOREQUEST;
76
  self->in = &get_DR_DEVICE_IOREQUEST;
77
78
  return rv;
79
}
80
81
int APP_CC construct_DR_CREATE_REQ(DR_CREATE_REQ * self) {
82
  int rv = 0;
83
84
  g_memset(self,0,sizeof(DR_CREATE_REQ));
85
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
86
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
87
  self->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
88
  self->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
89
  self->DeviceIoRequest.Header.__destructor = NULL;
90
  self->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
91
  self->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
92
  self->DeviceIoRequest.__destructor = NULL;
93
  self->out = &send_DR_CREATE_REQ;
94
  self->in = &get_DR_CREATE_REQ;
95
  self->DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
96
  self->CreateDisposition = FILE_OPEN;
97
  self->PathLength = 2;
98
99
  return rv;
100
}
101
102
int APP_CC construct_DR_CLOSE_REQ(DR_CLOSE_REQ * self) {
103
  int rv = 0;
104
105
  g_memset(self,0,sizeof(DR_CLOSE_REQ));
106
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
107
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
108
  self->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
109
  self->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
110
  self->DeviceIoRequest.Header.__destructor = NULL;
111
  self->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
112
  self->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
113
  self->DeviceIoRequest.__destructor = NULL;
114
  self->out = &send_DR_CLOSE_REQ;
115
  self->in = &get_DR_CLOSE_REQ;
116
  self->DeviceIoRequest.MajorFunction = IRP_MJ_CLOSE;
117
118
  return rv;
119
}
120
121
int APP_CC construct_DR_READ_REQ(DR_READ_REQ * self) {
122
  int rv = 0;
123
124
  g_memset(self,0,sizeof(DR_READ_REQ));
125
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
126
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
127
  self->in = &get_DR_READ_REQ;
128
  self->out = &send_DR_READ_REQ;
129
  self->DeviceIoRequest.MajorFunction = IRP_MJ_READ;
130
131
  return rv;
132
}
133
134
int APP_CC construct_DR_WRITE_REQ(DR_WRITE_REQ * self) {
135
  int rv = 0;
136
137
  g_memset(self,0,sizeof(DR_WRITE_REQ));
138
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
139
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
140
  self->in = &get_DR_WRITE_REQ;
141
  self->out = &send_DR_WRITE_REQ;
142
  self->DeviceIoRequest.MajorFunction = IRP_MJ_WRITE;
143
144
  return rv;
145
}
146
147
int APP_CC construct_DR_CONTROL_REQ(DR_CONTROL_REQ * self) {
148
  int rv = 0;
149
150
  g_memset(self,0,sizeof(DR_CONTROL_REQ));
151
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
152
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
153
  self->in = &get_DR_CONTROL_REQ;
154
  self->out = &send_DR_CONTROL_REQ;
155
  self->DeviceIoRequest.MajorFunction = IRP_MJ_DEVICE_CONTROL;
156
157
  return rv;
158
}
159
160
int APP_CC construct_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION * self) {
161
  int rv = 0;
162
163
  g_memset(self,0,sizeof(DR_DEVICE_IOCOMPLETION));
164
  construct_RDPDR_HEADER(&(self->Header));
165
  self->Header.in = &get_RDPDR_HEADER;
166
  self->Header.out = &send_RDPDR_HEADER;
167
  self->Header.__destructor = NULL;
168
  self->in = &get_DR_DEVICE_IOCOMPLETION;
169
  self->out = &send_DR_DEVICE_IOCOMPLETION;
170
171
  return rv;
172
}
173
174
int APP_CC construct_DR_CREATE_RSP(DR_CREATE_RSP * self) {
175
  int rv = 0;
176
177
  g_memset(self,0,sizeof(DR_CREATE_RSP));
178
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
179
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
180
  self->out = &send_DR_CREATE_RSP;
181
  self->in = &get_DR_CREATE_RSP;
182
183
  return rv;
184
}
185
186
int APP_CC construct_DR_CLOSE_RSP(DR_CLOSE_RSP * self) {
187
  int rv = 0;
188
189
  g_memset(self,0,sizeof(DR_CLOSE_RSP));
190
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
191
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
192
  self->out = &send_DR_CLOSE_RSP;
193
  self->in = &get_DR_CLOSE_RSP;
194
195
  return rv;
196
}
197
198
int APP_CC construct_DR_READ_RSP(DR_READ_RSP * self) {
199
  int rv = 0;
200
201
  g_memset(self,0,sizeof(DR_READ_RSP));
202
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
203
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
204
  self->out = &send_DR_READ_RSP;
205
  self->in = &get_DR_READ_RSP;
206
207
  return rv;
208
}
209
210
int APP_CC construct_DR_WRITE_RSP(DR_WRITE_RSP * self) {
211
  int rv = 0;
212
213
  g_memset(self,0,sizeof(DR_WRITE_RSP));
214
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
215
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
216
  self->out = &send_DR_WRITE_RSP;
217
  self->in = &get_DR_WRITE_RSP;
218
219
  return rv;
220
}
221
222
int APP_CC construct_DR_CONTROL_RSP(DR_CONTROL_RSP * self) {
223
  int rv = 0;
224
225
  g_memset(self,0,sizeof(DR_CONTROL_RSP));
226
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
227
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
228
  self->out = &send_DR_CONTROL_RSP;
229
  self->in = &get_DR_CONTROL_RSP;
230
231
  return rv;
232
}
233
234
int APP_CC construct_RDP_LOCK_INFO(RDP_LOCK_INFO * self) {
235
  int rv = 0;
236
237
  g_memset(self,0,sizeof(RDP_LOCK_INFO));
238
  self->out = &send_RDP_LOCK_INFO;
239
  self->in = &get_RDP_LOCK_INFO;
240
241
  return rv;
242
}
243
244
int APP_CC construct_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP * self) {
245
  int rv = 0;
246
247
  g_memset(self,0,sizeof(DR_CORE_DEVICE_ANNOUNCE_RSP));
248
  construct_RDPDR_HEADER(&(self->Header));
249
  self->out = &send_DR_CORE_DEVICE_ANNOUNCE_RSP;
250
  self->in = &get_DR_CORE_DEVICE_ANNOUNCE_RSP;
251
252
  return rv;
253
}
254
255
int APP_CC construct_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ * self) {
256
  int rv = 0;
257
258
  /* [MS-RDPEFS] — v20091104 @ p.31 */
259
  g_memset(self,0,sizeof(DR_CORE_SERVER_ANNOUNCE_REQ));
260
  construct_RDPDR_HEADER(&(self->Header));
261
  self->Header.Component = RDPDR_CTYP_CORE;
262
  self->Header.PacketId = PAKID_CORE_SERVER_ANNOUNCE;
263
  self->VersionMajor = 0x0001;
264
  self->VersionMinor = 0x000A;
265
  self->out = &send_DR_CORE_SERVER_ANNOUNCE_REQ;
266
  self->in = &get_DR_CORE_SERVER_ANNOUNCE_REQ;
267
268
  return rv;
269
}
270
271
int APP_CC construct_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP * self) {
272
  int rv = 0;
273
274
  g_memset(self,0,sizeof(DR_CORE_SERVER_ANNOUNCE_RSP));
275
  construct_RDPDR_HEADER(&(self->Header));
276
  self->in = &get_DR_CORE_SERVER_ANNOUNCE_RSP;
277
  self->out = &send_DR_CORE_SERVER_ANNOUNCE_RSP;
278
279
  return rv;
280
}
281
282
int APP_CC construct_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ * self) {
283
  int rv = 0;
284
285
  g_memset(self,0,sizeof(DR_CORE_CLIENT_NAME_REQ));
286
  construct_RDPDR_HEADER(&(self->Header));
287
  self->in = &get_DR_CORE_CLIENT_NAME_REQ;
288
  self->out = &send_DR_CORE_CLIENT_NAME_REQ;
289
290
  return rv;
291
}
292
293
int APP_CC construct_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM * self) {
294
  int rv = 0;
295
296
  g_memset(self,0,sizeof(DR_CORE_SERVER_CLIENTID_CONFIRM));
297
  construct_RDPDR_HEADER(&(self->Header));
298
  self->in = &get_DR_CORE_SERVER_CLIENTID_CONFIRM;
299
  self->out = &send_DR_CORE_SERVER_CLIENTID_CONFIRM;
300
301
  return rv;
302
}
303
304
int APP_CC construct_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ * self) {
305
  int rv = 0;
306
307
  GENERAL_CAPS_SET * generalcap = (GENERAL_CAPS_SET *)NULL;
308
  PRINTER_CAPS_SET * printercap = (PRINTER_CAPS_SET *)NULL;
309
  PORT_CAPS_SET * portcap = (PORT_CAPS_SET *)NULL;
310
  DRIVE_CAPS_SET * drivecap = (DRIVE_CAPS_SET *)NULL;
311
  SMARTCARD_CAPS_SET * smartcardcap = (SMARTCARD_CAPS_SET *)NULL;
312
313
  g_memset(self,0,sizeof(DR_CORE_CAPABILITY_REQ));
314
  
315
  generalcap = RDPDR_NEW(GENERAL_CAPS_SET);
316
  printercap = RDPDR_NEW(PRINTER_CAPS_SET);
317
  portcap = RDPDR_NEW(PORT_CAPS_SET);
318
  drivecap = RDPDR_NEW(DRIVE_CAPS_SET);
319
  smartcardcap = RDPDR_NEW(SMARTCARD_CAPS_SET);
320
  self->Header.Component = RDPDR_CTYP_CORE;
321
  self->Header.PacketId = PAKID_CORE_SERVER_CAPABILITY;
322
  self->out = &send_DR_CORE_CAPABILITY_REQ;
323
  self->in = &get_DR_CORE_CAPABILITY_REQ;
324
325
  return rv;
326
}
327
328
int APP_CC construct_GENERAL_CAPS_SET(GENERAL_CAPS_SET * self) {
329
  int rv = 0;
330
331
  g_memset(self,0,sizeof(GENERAL_CAPS_SET));
332
  construct_CAPABILITY_HEADER(&(self->Header));
333
  self->Header.CapabilityType = CAP_GENERAL_TYPE;
334
  self->Header.CapabilityLength = 8;
335
  self->Header.Version = GENERAL_CAPABILITY_VERSION_02;
336
  self->protocolMajorVersion = 0x0001;
337
  self->protocolMinorVersion = 0x000C;
338
  self->ioCode1 = RDPDR_IRP_MJ_CREATE | RDPDR_IRP_MJ_CLEANUP | RDPDR_IRP_MJ_CLOSE | RDPDR_IRP_MJ_READ | RDPDR_IRP_MJ_WRITE | RDPDR_IRP_MJ_FLUSH_BUFFERS | RDPDR_IRP_MJ_SHUTDOWN | RDPDR_IRP_MJ_DEVICE_CONTROL | RDPDR_IRP_MJ_QUERY_VOLUME_INFORMATION | RDPDR_IRP_MJ_SET_VOLUME_INFORMATION | RDPDR_IRP_MJ_QUERY_INFORMATION | RDPDR_IRP_MJ_SET_INFORMATION | RDPDR_IRP_MJ_DIRECTORY_CONTROL | RDPDR_IRP_MJ_LOCK_CONTROL;
339
  self->extendedPDU = RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU;
340
  self->extraFlags1 = ENABLE_ASYNCIO;
341
  self->Header.out = &send_CAPABILITY_HEADER;
342
  self->Header.in = &get_CAPABILITY_HEADER;
343
  self->out = &send_GENERAL_CAPS_SET;
344
  self->in = &get_GENERAL_CAPS_SET;
345
346
  return rv;
347
}
348
349
int APP_CC construct_PRINTER_CAPS_SET(PRINTER_CAPS_SET * self) {
350
  int rv = 0;
351
352
  g_memset(self,0,sizeof(PRINTER_CAPS_SET));
353
  construct_CAPABILITY_HEADER(&(self->Header));
354
  self->Header.out = &send_CAPABILITY_HEADER;
355
  self->Header.in = &get_CAPABILITY_HEADER;
356
  self->out = &send_PRINTER_CAPS_SET;
357
  self->in = &get_PRINTER_CAPS_SET;
358
  self->Header.CapabilityType = CAP_PRINTER_TYPE;
359
  self->Header.CapabilityLength = 8;
360
  self->Header.Version = PRINT_CAPABILITY_VERSION_01;
361
362
  return rv;
363
}
364
365
int APP_CC construct_PORT_CAPS_SET(PORT_CAPS_SET * self) {
366
  int rv = 0;
367
368
  g_memset(self,0,sizeof(PORT_CAPS_SET));
369
  construct_CAPABILITY_HEADER(&(self->Header));
370
  self->Header.out = &send_CAPABILITY_HEADER;
371
  self->Header.in = &get_CAPABILITY_HEADER;
372
  self->out = &send_PORT_CAPS_SET;
373
  self->in = &get_PORT_CAPS_SET;
374
  self->Header.CapabilityType = CAP_PORT_TYPE;
375
  self->Header.CapabilityLength = 8;
376
  self->Header.Version = PORT_CAPABILITY_VERSION_01;
377
378
  return rv;
379
}
380
381
int APP_CC construct_DRIVE_CAPS_SET(DRIVE_CAPS_SET * self) {
382
  int rv = 0;
383
384
  g_memset(self,0,sizeof(DRIVE_CAPS_SET));
385
  construct_CAPABILITY_HEADER(&(self->Header));
386
  self->Header.out = &send_CAPABILITY_HEADER;
387
  self->Header.in = &get_CAPABILITY_HEADER;
388
  self->out = &send_DRIVE_CAPS_SET;
389
  self->in = &get_DRIVE_CAPS_SET;
390
  self->Header.CapabilityType = CAP_DRIVE_TYPE;
391
  self->Header.CapabilityLength = 8;
392
  self->Header.Version = DRIVE_CAPABILITY_VERSION_02;
393
394
  return rv;
395
}
396
397
int APP_CC construct_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET * self) {
398
  int rv = 0;
399
400
  g_memset(self,0,sizeof(SMARTCARD_CAPS_SET));
401
  construct_CAPABILITY_HEADER(&(self->Header));
402
  self->Header.out = &send_CAPABILITY_HEADER;
403
  self->Header.in = &get_CAPABILITY_HEADER;
404
  self->out = &send_SMARTCARD_CAPS_SET;
405
  self->in = &get_SMARTCARD_CAPS_SET;
406
  self->Header.CapabilityType = CAP_SMARTCARD_TYPE;
407
  self->Header.CapabilityLength = 8;
408
  self->Header.Version = SMARTCARD_CAPABILITY_VERSION_01;
409
410
  return rv;
411
}
412
413
int APP_CC construct_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ * self) {
414
  int rv = 0;
415
416
  g_memset(self,0,sizeof(DR_CORE_DEVICELIST_ANNOUNCE_REQ));
417
  construct_RDPDR_HEADER(&(self->Header));
418
  self->out = &send_DR_CORE_DEVICELIST_ANNOUNCE_REQ;
419
  self->in = &get_DR_CORE_DEVICELIST_ANNOUNCE_REQ;
420
421
  return rv;
422
}
423
424
int APP_CC construct_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE * self) {
425
  int rv = 0;
426
  int idx = 0;
427
428
  //g_memset(self,0,sizeof(DR_DEVICELIST_ANNOUNCE));
429
  construct_RDPDR_HEADER(&(self->Header));
430
  self->Header.Component = RDPDR_CTYP_CORE;
431
  self->Header.PacketId = PAKID_CORE_DEVICELIST_ANNOUNCE;
432
  self->Header.out = &send_RDPDR_HEADER;
433
  self->Header.in = &get_RDPDR_HEADER;
434
  self->Header.__destructor = NULL;
435
  self->out = &send_DR_DEVICELIST_ANNOUNCE;
436
  self->in = &get_DR_DEVICELIST_ANNOUNCE;
437
  self->__destructor = NULL;
438
439
  if (self->DeviceCount > 0) {
440
    self->DeviceList = (DEVICE_ANNOUNCE **)g_malloc(sizeof(size_t) * self->DeviceCount, 1);
441
    for (idx = 0; idx < self->DeviceCount; idx++) {
442
      self->DeviceList[idx] = (DEVICE_ANNOUNCE *)g_malloc(sizeof(DEVICE_ANNOUNCE), 1);
443
    }
444
  }
445
446
  return rv;
447
}
448
449
int APP_CC construct_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE * self) {
450
  int rv = 0;
451
452
  g_memset(self,0,sizeof(DR_DEVICELIST_REMOVE));
453
  construct_RDPDR_HEADER(&(self->Header));
454
  self->out = &send_DR_DEVICELIST_REMOVE;
455
  self->in = &get_DR_DEVICELIST_REMOVE;
456
457
  return rv;
458
}
459
460
int APP_CC construct_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST * self) {
461
  int rv = 0;
462
463
  g_memset(self,0,sizeof(DR_DRIVE_CORE_DEVICE_IOREQUEST));
464
  construct_RDPDR_HEADER(&(self->Header.Header));
465
  construct_DR_DEVICE_IOREQUEST(&(self->Header));
466
  self->Header.Header.out = &send_RDPDR_HEADER;
467
  self->Header.Header.in = &get_RDPDR_HEADER;
468
  self->Header.Header.__destructor = NULL;
469
  self->Header.out = &send_DR_DEVICE_IOREQUEST;
470
  self->Header.in = &get_DR_DEVICE_IOREQUEST;
471
  self->Header.__destructor = NULL;
472
  self->out = &send_DR_DRIVE_CORE_DEVICE_IOREQUEST;
473
  self->in = &get_DR_DRIVE_CORE_DEVICE_IOREQUEST;
474
  self->__destructor = NULL;
475
476
  return rv;
477
}
478
479
int APP_CC construct_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ * self) {
480
  int rv = 0;
481
482
  g_memset(self,0,sizeof(DR_DRIVE_CREATE_REQ));
483
  construct_RDPDR_HEADER(&(self->DeviceCreateRequest.DeviceIoRequest.Header));
484
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceCreateRequest.DeviceIoRequest));
485
  construct_DR_CREATE_REQ(&(self->DeviceCreateRequest));
486
  self->DeviceCreateRequest.DeviceIoRequest.Header.Component = RDPDR_CTYP_CORE;
487
  self->DeviceCreateRequest.DeviceIoRequest.Header.PacketId = PAKID_CORE_DEVICE_IOREQUEST;
488
  self->DeviceCreateRequest.DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
489
  self->DeviceCreateRequest.DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
490
  self->DeviceCreateRequest.DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
491
  self->DeviceCreateRequest.DeviceIoRequest.Header.__destructor = NULL;
492
  self->DeviceCreateRequest.DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
493
  self->DeviceCreateRequest.DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
494
  self->DeviceCreateRequest.DeviceIoRequest.__destructor = NULL;
495
  self->DeviceCreateRequest.out = &send_DR_CREATE_REQ;
496
  self->DeviceCreateRequest.in = &get_DR_CREATE_REQ;
497
  self->DeviceCreateRequest.__destructor = NULL;
498
  self->out = &send_DR_DRIVE_CREATE_REQ;
499
  self->in = &get_DR_DRIVE_CREATE_REQ;
500
  self->__destructor = NULL;
501
502
  return rv;
503
}
504
505
int APP_CC construct_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ * self) {
506
  int rv = 0;
507
508
  g_memset(self,0,sizeof(DR_DRIVE_CLOSE_REQ));
509
  construct_RDPDR_HEADER(&(self->DeviceCloseRequest.DeviceIoRequest.Header));
510
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceCloseRequest.DeviceIoRequest));
511
  construct_DR_CLOSE_REQ(&(self->DeviceCloseRequest));
512
  self->out = &send_DR_DRIVE_CLOSE_REQ;
513
  self->in = &get_DR_DRIVE_CLOSE_REQ;
514
515
  self->DeviceCloseRequest.DeviceIoRequest.MajorFunction = IRP_MJ_CLOSE;
516
517
  return rv;
518
}
519
520
int APP_CC construct_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ * self) {
521
  int rv = 0;
522
523
  g_memset(self,0,sizeof(DR_DRIVE_READ_REQ));
524
  construct_RDPDR_HEADER(&(self->DeviceReadRequest.DeviceIoRequest.Header));
525
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceReadRequest.DeviceIoRequest));
526
  construct_DR_READ_REQ(&(self->DeviceReadRequest));
527
  self->out = &send_DR_DRIVE_READ_REQ;
528
  self->in = &get_DR_DRIVE_READ_REQ;
529
  self->DeviceReadRequest.DeviceIoRequest.MajorFunction = IRP_MJ_READ;
530
531
  return rv;
532
}
533
534
int APP_CC construct_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ * self) {
535
  int rv = 0;
536
537
  g_memset(self,0,sizeof(DR_DRIVE_WRITE_REQ));
538
  construct_RDPDR_HEADER(&(self->DeviceWriteRequest.DeviceIoRequest.Header));
539
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceWriteRequest.DeviceIoRequest));
540
  construct_DR_WRITE_REQ(&(self->DeviceWriteRequest));
541
  self->out = &send_DR_DRIVE_WRITE_REQ;
542
  self->in = &get_DR_DRIVE_WRITE_REQ;
543
544
  self->DeviceWriteRequest.DeviceIoRequest.MajorFunction = IRP_MJ_WRITE;
545
546
  return rv;
547
}
548
549
int APP_CC construct_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ * self) {
550
  int rv = 0;
551
552
  g_memset(self,0,sizeof(DR_DRIVE_CONTROL_REQ));
553
  construct_RDPDR_HEADER(&(self->Header.DeviceIoRequest.Header));
554
  construct_DR_DEVICE_IOREQUEST(&(self->Header.DeviceIoRequest));
555
  construct_DR_CONTROL_REQ(&(self->Header));
556
  self->out = &send_DR_DRIVE_CONTROL_REQ;
557
  self->in = &get_DR_DRIVE_CONTROL_REQ;
558
559
  self->Header.DeviceIoRequest.MajorFunction = IRP_MJ_DEVICE_CONTROL;
560
561
  return rv;
562
}
563
564
int APP_CC construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ * self) {
565
  int rv = 0;
566
567
  g_memset(self,0,sizeof(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ));
568
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
569
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
570
  self->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
571
  self->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
572
  self->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
573
  self->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
574
  self->in = &get_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ;
575
  self->out = &send_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ;
576
  self->__destructor = NULL;
577
  self->DeviceIoRequest.Header.__destructor = NULL;
578
  self->DeviceIoRequest.__destructor = NULL;
579
  self->DeviceIoRequest.MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
580
  self->FsInformationClass = FileFsVolumeInformation;
581
  rv = sizeof(FILE_FS_VOLUME_INFORMATION) + (sizeof(char) * 128);
582
  self->QueryVolumeBuffer.FsVolumeInformation = (FILE_FS_VOLUME_INFORMATION *)g_malloc(rv, 1);
583
  self->Length = rv;
584
  rv = 0;
585
586
  return rv;
587
}
588
589
int APP_CC construct_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ * self) {
590
  int rv = 0;
591
592
  g_memset(self,0,sizeof(DR_DRIVE_SET_VOLUME_INFORMATION_REQ));
593
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
594
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
595
  self->DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
596
  //self->DeviceIoRequest.MinorFunction = 0x00000000;
597
  self->FsInformationClass = FileBasicInformation;
598
  self->out = &send_DR_DRIVE_SET_VOLUME_INFORMATION_REQ;
599
  self->in = &get_DR_DRIVE_SET_VOLUME_INFORMATION_REQ;
600
601
  return rv;
602
}
603
604
int APP_CC construct_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ * self) {
605
  /*	[MS-RDPEFS] @ 2.2.3.3.10		*/
606
  int rv = 0;
607
608
  g_memset(self,0,sizeof(DR_DRIVE_QUERY_INFORMATION_REQ));
609
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
610
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
611
  self->__destructor = NULL;
612
  self->DeviceIoRequest.__destructor = NULL;
613
  self->DeviceIoRequest.Header.__destructor = NULL;
614
  self->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
615
  self->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
616
  self->out = &send_DR_DRIVE_QUERY_INFORMATION_REQ;
617
  self->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
618
  self->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
619
  self->in = &get_DR_DRIVE_QUERY_INFORMATION_REQ;
620
  self->DeviceIoRequest.MajorFunction = IRP_MJ_QUERY_INFORMATION;
621
  self->DeviceIoRequest.MinorFunction = 0x00000000;
622
  self->FsInformationClass = FileBasicInformation;
623
  self->Length = 40;		/* UTF-16 null terminator */
624
625
  return rv;
626
}
627
628
int APP_CC construct_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ * self) {
629
  int rv = 0;
630
631
  g_memset(self,0,sizeof(DR_DRIVE_SET_INFORMATION_REQ));
632
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
633
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
634
  self->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
635
  self->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
636
  self->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
637
  self->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
638
  self->DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
639
  self->DeviceIoRequest.MinorFunction = 0x00000000;
640
  self->FsInformationClass = FileBasicInformation;
641
  self->out = &send_DR_DRIVE_SET_INFORMATION_REQ;
642
  self->in = &get_DR_DRIVE_SET_INFORMATION_REQ;
643
644
  return rv;
645
}
646
647
int APP_CC construct_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION * self) {
648
  int rv = 0;
649
650
  g_memset(self,0,sizeof(RDP_FILE_RENAME_INFORMATION));
651
652
  return rv;
653
}
654
655
int APP_CC construct_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ * self) {
656
  int rv = 0;
657
658
  if (self != NULL) {
659
    g_memset(self,0,sizeof(DR_DRIVE_QUERY_DIRECTORY_REQ));
660
    construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
661
    construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
662
    self->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
663
    self->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
664
    self->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
665
    self->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
666
    self->in = &get_DR_DRIVE_QUERY_DIRECTORY_REQ;
667
    self->out = &send_DR_DRIVE_QUERY_DIRECTORY_REQ;
668
    self->setPath = &setPath_DR_DRIVE_QUERY_DIRECTORY_REQ;
669
    self->DeviceIoRequest.MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
670
    self->DeviceIoRequest.MinorFunction = IRP_MN_QUERY_DIRECTORY;
671
    self->DeviceIoRequest.DeviceId = 0;
672
    self->DeviceIoRequest.FileId = 0x00000001;
673
    self->DeviceIoRequest.CompletionId = 0x00000000;
674
    self->FsInformationClass = FileBothDirectoryInformation;
675
    self->PathLength = 0x00000002;
676
    self->InitialQuery = 0x01;
677
    self->DeviceIoRequest.MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
678
    self->DeviceIoRequest.MinorFunction = IRP_MN_QUERY_DIRECTORY;
679
    self->DeviceIoRequest.Header.__destructor = NULL;
680
    self->DeviceIoRequest.__destructor = NULL;
681
    self->__destructor = NULL;
682
  }
683
  else {
684
    rv = -1;
685
  }
686
687
  return rv;
688
}
689
690
int APP_CC construct_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ * self) {
691
  int rv = 0;
692
693
  g_memset(self,0,sizeof(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ));
694
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
695
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
696
  self->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
697
  self->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
698
  self->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
699
  self->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
700
701
  self->DeviceIoRequest.MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
702
  self->DeviceIoRequest.MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
703
  self->WatchTree = 0x00;
704
  self->CompletionFilter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_CREATION;
705
  self->in = &get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ;
706
  self->out = &send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ;
707
708
  return rv;
709
}
710
711
int APP_CC construct_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ * self) {
712
  int rv = 0;
713
714
  g_memset(self,0,sizeof(DR_DRIVE_LOCK_REQ));
715
  construct_RDPDR_HEADER(&(self->DeviceIoRequest.Header));
716
  construct_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest));
717
  self->out = &send_DR_DRIVE_LOCK_REQ;
718
  self->in = &get_DR_DRIVE_LOCK_REQ;
719
720
  return rv;
721
}
722
723
int APP_CC construct_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION * self) {
724
  int rv = 0;
725
726
  g_memset(self,0,sizeof(DR_DRIVE_CORE_DEVICE_IOCOMPLETION));
727
  construct_RDPDR_HEADER(&(self->DeviceIoResponse.Header));
728
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoResponse));
729
  self->DeviceIoResponse.Header.out = &send_RDPDR_HEADER;
730
  self->DeviceIoResponse.Header.in = &get_RDPDR_HEADER;
731
  self->DeviceIoResponse.Header.__destructor = NULL;
732
  self->DeviceIoResponse.__destructor = NULL;
733
  self->DeviceIoResponse.out = &send_DR_DEVICE_IOCOMPLETION;
734
  self->DeviceIoResponse.in = &get_DR_DEVICE_IOCOMPLETION;
735
  self->out = &send_DR_DRIVE_CORE_DEVICE_IOCOMPLETION;
736
  self->in = &get_DR_DRIVE_CORE_DEVICE_IOCOMPLETION;
737
  self->__destructor = NULL;
738
739
  return rv;
740
}
741
742
int APP_CC construct_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP * self) {
743
  int rv = 0;
744
745
  g_memset(self,0,sizeof(DR_DRIVE_CREATE_RSP));
746
  construct_RDPDR_HEADER(&(self->DeviceCreateResponse.DeviceIoReply.Header));
747
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceCreateResponse.DeviceIoReply));
748
  construct_DR_CREATE_RSP(&(self->DeviceCreateResponse));
749
  self->DeviceCreateResponse.DeviceIoReply.Header.out = &send_RDPDR_HEADER;
750
  self->DeviceCreateResponse.DeviceIoReply.Header.in = &get_RDPDR_HEADER;
751
  self->DeviceCreateResponse.DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
752
  self->DeviceCreateResponse.DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
753
  self->DeviceCreateResponse.out = &send_DR_CREATE_RSP;
754
  self->DeviceCreateResponse.in = &get_DR_CREATE_RSP;
755
  self->out = &send_DR_DRIVE_CREATE_RSP;
756
  self->in = &get_DR_DRIVE_CREATE_RSP;
757
758
  return rv;
759
}
760
761
int APP_CC construct_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP * self) {
762
  int rv = 0;
763
764
  g_memset(self,0,sizeof(DR_DRIVE_CLOSE_RSP));
765
  construct_DR_CLOSE_RSP(&(self->DeviceCloseResponse));
766
  self->DeviceCloseResponse.out = &send_DR_CLOSE_RSP;
767
  self->DeviceCloseResponse.in = &get_DR_CLOSE_RSP;
768
  self->out = &send_DR_DRIVE_CLOSE_RSP;
769
  self->in = &get_DR_DRIVE_CLOSE_RSP;
770
771
  return rv;
772
}
773
774
int APP_CC construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP * self) {
775
  int rv = 0;
776
777
  g_memset(self,0,sizeof(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP));
778
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
779
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
780
  self->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
781
  self->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
782
  self->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
783
  self->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
784
  self->in = &get_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP;
785
  self->out = &send_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP;
786
787
  return rv;
788
}
789
790
int APP_CC construct_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP * self) {
791
  int rv = 0;
792
793
  g_memset(self,0,sizeof(DR_DRIVE_SET_VOLUME_INFORMATION_RSP));
794
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
795
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
796
  self->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
797
  self->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
798
  self->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
799
  self->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
800
  self->out = &send_DR_DRIVE_SET_VOLUME_INFORMATION_RSP;
801
  self->in = &get_DR_DRIVE_SET_VOLUME_INFORMATION_RSP;
802
803
  return rv;
804
}
805
806
int APP_CC construct_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP * self) {
807
  int rv = 0;
808
809
  g_memset(self,0,sizeof(DR_DRIVE_QUERY_INFORMATION_RSP));
810
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
811
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
812
  self->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
813
  self->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
814
  self->DeviceIoReply.Header.__destructor = NULL;
815
  self->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
816
  self->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
817
  self->DeviceIoReply.__destructor = NULL;
818
  self->in = &get_DR_DRIVE_QUERY_INFORMATION_RSP;
819
  self->out = &send_DR_DRIVE_QUERY_INFORMATION_RSP;
820
  self->__destructor = NULL;
821
822
  return rv;
823
}
824
825
int APP_CC construct_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP * self) {
826
  int rv = 0;
827
828
  g_memset(self,0,sizeof(DR_DRIVE_QUERY_DIRECTORY_RSP));
829
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
830
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
831
  self->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
832
  self->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
833
  self->DeviceIoReply.Header.__destructor = NULL;
834
  self->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
835
  self->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
836
  self->DeviceIoReply.__destructor = NULL;
837
  self->in = &get_DR_DRIVE_QUERY_DIRECTORY_RSP;
838
  self->out = &send_DR_DRIVE_QUERY_DIRECTORY_RSP;
839
  self->__destructor = NULL;
840
841
  return rv;
842
}
843
844
int APP_CC construct_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP * self) {
845
  int rv = 0;
846
847
  g_memset(self,0,sizeof(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP));
848
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
849
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
850
  self->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
851
  self->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
852
  self->DeviceIoReply.Header.__destructor = NULL;
853
  self->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
854
  self->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
855
  self->DeviceIoReply.__destructor = NULL;
856
  self->in = &get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP;
857
  self->out = &send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP;
858
  self->__destructor = NULL;
859
860
  return rv;
861
}
862
863
int APP_CC construct_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP * self) {
864
  int rv = 0;
865
866
  g_memset(self,0,sizeof(DR_DRIVE_LOCK_RSP));
867
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
868
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
869
  self->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
870
  self->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
871
  self->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
872
  self->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
873
  self->in = &get_DR_DRIVE_LOCK_RSP;
874
  self->out = &send_DR_DRIVE_LOCK_RSP;
875
876
  return rv;
877
}
878
879
int APP_CC construct_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON * self) {
880
  int rv = 0;
881
882
  g_memset(self,0,sizeof(DR_CORE_USER_LOGGEDON));
883
  construct_RDPDR_HEADER(&(self->Header));
884
  self->Header.in = &get_RDPDR_HEADER;
885
  self->Header.out = &send_RDPDR_HEADER;
886
  self->in = &get_DR_CORE_USER_LOGGEDON;
887
  self->out = &send_DR_CORE_USER_LOGGEDON;
888
  self->Header.Component = RDPDR_CTYP_CORE;
889
  self->Header.PacketId = PAKID_CORE_USER_LOGGEDON;
890
891
  return rv;
892
}
893
894
int APP_CC construct_DR_DRIVE_SET_INFORMATION_RSP(DR_DRIVE_SET_INFORMATION_RSP * self) {
895
  int rv = 0;
896
897
  g_memset(self,0,sizeof(DR_DRIVE_SET_INFORMATION_RSP));
898
  construct_RDPDR_HEADER(&(self->DeviceIoReply.Header));
899
  construct_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply));
900
  self->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
901
  self->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
902
  self->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
903
  self->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
904
  self->out = &send_DR_DRIVE_SET_INFORMATION_RSP;
905
  self->in = &get_DR_DRIVE_SET_INFORMATION_RSP;
906
907
  return rv;
908
}
909
910
int APP_CC construct_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 * self) {
911
  int rv = 0;
912
  uint8_t hdr = 0x00;
913
  uint8_t cmd = 0x00;
914
  uint8_t sp = 0x00;
915
  uint8_t cb = 0x00;
916
917
  if (self == NULL) {
918
    rv = -1;
919
    goto end;
920
  }
921
922
  cmd = DRDYNVC_CAPABILITIES;
923
  sp = 0x00;
924
  cb = 0x00;
925
  hdr = (cmd << 4) | (sp << 2) | (cb);
926
927
  g_memset(self, 0x00, sizeof(DYNVC_CAPS_VERSION2));
928
  self->Cmd = DRDYNVC_CAPABILITIES;
929
  self->Sp = 0x00;
930
  self->cbChId = DRDYNVC_NONE;
931
  self->Pad = 0x00;
932
  self->Version = DRDYNVC_VERSION2;
933
  self->PriorityCharge0 = 0x00000000;
934
  self->PriorityCharge1 = 0x00000000;
935
  self->PriorityCharge2 = 0x00000000;
936
  self->PriorityCharge3 = 0x00000000;
937
  self->in = &get_DYNVC_CAPS_VERSION2;
938
  self->out = &send_DYNVC_CAPS_VERSION2;
939
  self->destroy = &destroy_DYNVC_CAPS_VERSION2;
940
941
 end:;
942
  return rv;
943
}
944
945
int APP_CC construct_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 * self) {
946
  int rv = 0;
947
948
  if (self == NULL) {
949
    rv = -1;
950
    goto end;
951
  }
952
953
  g_memset(self, 0x00, sizeof(DYNVC_CAPS_VERSION1));
954
  self->Cmd = DRDYNVC_CAPABILITIES;
955
  self->Sp = 0x02;
956
  self->cbChId = DRDYNVC_NONE;
957
  self->Pad = 0x00;
958
  self->Version = DRDYNVC_VERSION1;
959
  self->in = &get_DYNVC_CAPS_VERSION1;
960
  self->out = &send_DYNVC_CAPS_VERSION1;
961
  self->destroy = &destroy_DYNVC_CAPS_VERSION1;
962
963
 end:;
964
  return rv;
965
}
966
967
int APP_CC construct_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP * self) {
968
  int rv = 0;
969
970
  if (self == NULL) {
971
    rv = -1;
972
    goto end;
973
  }
974
975
  g_memset(self, 0x00, sizeof(DYNVC_CAPS_VERSION1));
976
  self->Cmd = DRDYNVC_CAPABILITIES;
977
  self->Sp = 0x02;
978
  self->cbChId = DRDYNVC_NONE;
979
  self->Pad = 0x00;
980
  self->Version = DRDYNVC_VERSION2;
981
  self->in = &get_DYNVC_CAPS_RSP;
982
  self->out = &send_DYNVC_CAPS_RSP;
983
  self->destroy = &destroy_DYNVC_CAPS_RSP;
984
985
 end:;
986
  return rv;
987
}
988
989
int APP_CC construct_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ * self) {
990
  int rv = 0;
991
992
  if (self == NULL) {
993
    rv = -1;
994
    goto end;
995
  }
996
997
  g_memset(self, 0x00, sizeof(DYNVC_CREATE_REQ));
998
  self->Cmd = DRDYNVC_CREATE;
999
  self->Pri = 0x00;
1000
  self->cbChId = DRDYNVC_BYTE;
1001
  self->in = &get_DYNVC_CREATE_REQ;
1002
  self->out = &send_DYNVC_CREATE_REQ;
1003
  self->destroy = &destroy_DYNVC_CREATE_REQ;
1004
1005
 end:;
1006
  return rv;
1007
}
1008
1009
int APP_CC construct_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP * self) {
1010
  int rv = 0;
1011
1012
  if (self == NULL) {
1013
    rv = -1;
1014
    goto end;
1015
  }
1016
1017
  g_memset(self, 0x00, sizeof(DYNVC_CREATE_RSP));
1018
  self->Cmd = DRDYNVC_CREATE;
1019
  self->in = &get_DYNVC_CREATE_RSP;
1020
  self->out = &send_DYNVC_CREATE_RSP;
1021
  self->destroy = &destroy_DYNVC_CREATE_RSP;
1022
1023
 end:;
1024
  return rv;
1025
}
1026
1027
int APP_CC construct_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST * self) {
1028
  int rv = 0;
1029
1030
  if (self == NULL) {
1031
    rv = -1;
1032
    goto end;
1033
  }
1034
1035
  g_memset(self, 0x00, sizeof(DYNVC_DATA_FIRST));
1036
1037
  self->Cmd = DRDYNVC_DATAFIRST;
1038
  self->Len = DRDYNVC_WORD;
1039
  self->cbChId = DRDYNVC_BYTE;
1040
  self->ChannelId = 0x01;
1041
  self->in = &get_DYNVC_DATA_FIRST;
1042
  self->out = &send_DYNVC_DATA_FIRST;
1043
  self->destroy = &destroy_DYNVC_DATA_FIRST;
1044
1045
 end:;
1046
  return rv;
1047
}
1048
1049
int APP_CC construct_DYNVC_DATA(DYNVC_DATA * self) {
1050
  int rv = 0;
1051
1052
  if (self == NULL) {
1053
    rv = -1;
1054
    goto end;
1055
  }
1056
1057
  g_memset(self, 0x00, sizeof(DYNVC_DATA));
1058
  self->Cmd = DRDYNVC_DATA;
1059
  self->Sp = DRDYNVC_NONE;
1060
  self->cbChId = DRDYNVC_BYTE;
1061
  self->in = &get_DYNVC_DATA;
1062
  self->out = &send_DYNVC_DATA;
1063
  self->destroy = &destroy_DYNVC_DATA;
1064
1065
 end:;
1066
  return rv;
1067
}
1068
1069
int APP_CC construct_DYNVC_CLOSE(DYNVC_CLOSE * self) {
1070
  int rv = 0;
1071
1072
  if (self == NULL) {
1073
    rv = -1;
1074
    goto end;
1075
  }
1076
1077
  g_memset(self, 0x00, sizeof(DYNVC_CLOSE));
1078
  self->Cmd = DRDYNVC_CLOSE;
1079
  self->Sp = DRDYNVC_NONE;
1080
  self->cbChId = DRDYNVC_BYTE;
1081
  self->in = &get_DYNVC_CLOSE;
1082
  self->out = &send_DYNVC_CLOSE;
1083
  self->destroy = &destroy_DYNVC_CLOSE;
1084
1085
 end:;
1086
  return rv;
1087
}
1088
1089
1090
int APP_CC construct_MSG_SNDIN_VERSION(MSG_SNDIN_VERSION * self) {
1091
    int rv = 0;
1092
1093
    if (self == NULL) {
1094
      rv = -1;
1095
      goto end;
1096
    }
1097
1098
    self->Header.MessageId = CMSG_SNDIN_VERSION;
1099
    self->Version = SNDIN_VERSION;
1100
1101
  end:;
1102
    return rv;
1103
}
1104
1105
int APP_CC construct_MSG_SNDIN_FORMATS(MSG_SNDIN_FORMATS * self) {
1106
    int rv = 0;
1107
1108
    if (self == NULL) {
1109
      rv = -1;
1110
      goto end;
1111
    }
1112
1113
    self->Header.MessageId = CMSG_SNDIN_FORMATS;
1114
    self->cbSizeFormatsPacket = 0x80000000;
1115
1116
  end:;
1117
    return rv;
1118
}
1119
1120
int APP_CC construct_MSG_SNDIN_OPEN(MSG_SNDIN_OPEN * self) {
1121
    int rv = 0;
1122
    WAVEFORMAT_EXTENSIBLE * buf = (WAVEFORMAT_EXTENSIBLE *)NULL;
1123
    const GUID tguid = KSDATAFORMAT_SUBTYPE_PCM;
1124
1125
    if (self == NULL) {
1126
      rv = -1;
1127
      goto end;
1128
    }
1129
1130
    self->initialFormat = 0x00000001;
1131
    self->FramesPerPacket = 0x00000000;
1132
    self->Header.MessageId = CMSG_SNDIN_OPEN;
1133
    self->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
1134
    self->cbSize = sizeof(GUID);
1135
    buf = (WAVEFORMAT_EXTENSIBLE *)(self->ExtraFormatData);
1136
    g_memcpy(&(buf->SubFormat),&tguid,sizeof(GUID));
1137
    self->nChannels = 0x02;
1138
    self->nSamplesPerSec = 0x00000000;
1139
    self->nAvgBytesPerSec = 0x00000000;
1140
    self->nBlockAlign = 0x0000;
1141
    self->wBitsPerSample = 0x00000000;
1142
1143
  end:;
1144
    return rv;
1145
}
1146
1147
int APP_CC construct_WAVEFORMAT_EXTENSIBLE(WAVEFORMAT_EXTENSIBLE * self) {
1148
    int rv = 0;
1149
    const GUID tguid = KSDATAFORMAT_SUBTYPE_PCM;
1150
1151
    if (self == NULL) {
1152
      rv = -1;
1153
      goto end;
1154
    }
1155
1156
    g_memcpy(&(self->SubFormat), &tguid, sizeof(GUID));
1157
1158
  end:;
1159
    return rv;
1160
}
1161
1162
int APP_CC construct_MSG_SNDIN_OPEN_REPLY(MSG_SNDIN_OPEN_REPLY * self) {
1163
    int rv = 0;
1164
1165
    if (self == NULL) {
1166
      rv = -1;
1167
      goto end;
1168
    }
1169
1170
    self->Header.MessageId = CMSG_SNDIN_OPEN_REPLY;
1171
1172
  end:;
1173
    return rv;
1174
}
1175
1176
int APP_CC construct_MSG_SNDIN_DATA_INCOMING(MSG_SNDIN_DATA_INCOMING * self) {
1177
    int rv = 0;
1178
1179
    if (self == NULL) {
1180
      rv = -1;
1181
      goto end;
1182
    }
1183
1184
    self->Header.MessageId = CMSG_SNDIN_DATA_INCOMING;
1185
1186
  end:;
1187
    return rv;
1188
}
1189
1190
int APP_CC construct_MSG_SNDIN_DATA(MSG_SNDIN_DATA * self) {
1191
    int rv = 0;
1192
1193
    if (self == NULL) {
1194
      rv = -1;
1195
      goto end;
1196
    }
1197
1198
    self->Header.MessageId = CMSG_SNDIN_DATA;
1199
1200
  end:;
1201
    return rv;
1202
}
1203
1204
int APP_CC construct_MSG_SNDIN_FORMATCHANGE(MSG_SNDIN_FORMATCHANGE * self) {
1205
    int rv = 0;
1206
1207
    if (self == NULL) {
1208
      rv = -1;
1209
      goto end;
1210
    }
1211
1212
    self->Header.MessageId = CMSG_SNDIN_FORMATCHANGE;
1213
1214
  end:;
1215
    return rv;
1216
}
1217
1218
/*
1219
int APP_CC construct_( * self) {
1220
  int rv = 0;
1221
  return rv;
1222
}
1223
*/
1224
1225
/**********************************************************************
1226
 *		END:	CONSTRUCTORS
1227
 **********************************************************************/
1228
1229
1230
/**********************************************************************
1231
 *		BEGIN:	SENDERS / GETTERS
1232
 **********************************************************************/
1233
1234
int APP_CC send_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ * self, struct stream * s) {
1235
  int rv = 0;
1236
1237
  send_RDPDR_HEADER(&(self->Header), s);
1238
  out_uint16_le(s, self->VersionMajor);
1239
  out_uint16_le(s, self->VersionMinor);
1240
  out_uint32_le(s, self->ClientId);
1241
1242
  return rv;
1243
}
1244
1245
int APP_CC send_RDPDR_HEADER(RDPDR_HEADER * self, struct stream * s) {
1246
  int rv = 0;
1247
1248
  if (self == NULL || s == NULL) {
1249
    // MDBGLOG("redir","send_RDPDR_HEADER(): empty self or null stream");
1250
    rv = -1;
1251
  }
1252
  else {
1253
    out_uint16_le(s, self->Component);
1254
    out_uint16_le(s, self->PacketId);
1255
  }
1256
1257
  return rv;
1258
}
1259
1260
int APP_CC get_RDPDR_HEADER(RDPDR_HEADER * self, struct stream * s) {
1261
  int rv = 0;
1262
1263
  if (self == NULL || s == NULL) {
1264
    // MDBGLOG("redir","get_RDPDR_HEADER(): empty self or null stream");
1265
    rv = -1;
1266
  }
1267
  else {
1268
    in_uint16_le(s, self->Component);
1269
    in_uint16_le(s, self->PacketId);
1270
  }
1271
1272
  return rv;
1273
}
1274
1275
int APP_CC get_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP * self, struct stream * s) {
1276
  int rv = 0;
1277
1278
  get_RDPDR_HEADER(&(self->Header), s);
1279
  in_uint16_le(s, self->VersionMajor);
1280
  in_uint16_le(s, self->VersionMinor);
1281
  in_uint32_le(s, self->ClientId);
1282
1283
  return rv;
1284
}
1285
1286
int APP_CC get_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ * self, struct stream * s) {
1287
  int rv = 0;
1288
1289
  get_RDPDR_HEADER(&(self->Header), s);
1290
  in_uint32_le(s, self->UnicodeFlag);
1291
  in_uint32_le(s, self->CodePage);
1292
  in_uint32_le(s, self->ComputerNameLen);
1293
  if (self->ComputerNameLen > 0) {
1294
    self->ComputerName = (BYTE *)g_malloc(sizeof(BYTE) * self->ComputerNameLen,1);
1295
    in_uint8a(s, self->ComputerName, self->ComputerNameLen);
1296
  }
1297
1298
  return rv;
1299
}
1300
1301
int APP_CC send_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON * self, struct stream * s) {
1302
  int rv = 0;
1303
1304
  send_RDPDR_HEADER(&(self->Header), s);
1305
1306
  return rv;
1307
}
1308
1309
int APP_CC
1310
get_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON * self, struct stream * s) {
1311
  int rv = 0;
1312
1313
  get_RDPDR_HEADER(&(self->Header), s);
1314
1315
  return rv;
1316
}
1317
1318
int APP_CC send_CAPABILITY_HEADER(CAPABILITY_HEADER * self, struct stream * s) {
1319
  int rv = 0;
1320
1321
  out_uint16_le(s, self->CapabilityType);
1322
  out_uint16_le(s, self->CapabilityLength);
1323
  out_uint32_le(s, self->Version);
1324
1325
  return rv;
1326
}
1327
1328
int APP_CC get_CAPABILITY_HEADER(CAPABILITY_HEADER * self, struct stream * s) {
1329
  int rv = 0;
1330
1331
  in_uint16_le(s, self->CapabilityType);
1332
  in_uint16_le(s, self->CapabilityLength);
1333
  in_uint32_le(s, self->Version);
1334
1335
  return rv;
1336
}
1337
1338
int APP_CC
1339
send_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST * self, struct stream * s) {
1340
  int rv = 0;
1341
1342
  send_RDPDR_HEADER(&(self->Header), s);
1343
  out_uint32_le(s, self->DeviceId);
1344
  out_uint32_le(s, self->FileId);
1345
  out_uint32_le(s, self->CompletionId);
1346
  out_uint32_le(s, self->MajorFunction);
1347
  out_uint32_le(s, self->MinorFunction);
1348
1349
  return rv;
1350
}
1351
1352
int APP_CC
1353
get_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST * self, struct stream * s) {
1354
  int rv = 0;
1355
1356
  get_RDPDR_HEADER(&(self->Header), s);
1357
  in_uint32_le(s, self->DeviceId);
1358
  in_uint32_le(s, self->FileId);
1359
  in_uint32_le(s, self->CompletionId);
1360
  in_uint32_le(s, self->MajorFunction);
1361
  in_uint32_le(s, self->MinorFunction);
1362
1363
  return rv;
1364
}
1365
1366
int APP_CC send_DR_CREATE_REQ(DR_CREATE_REQ * self, struct stream * s) {
1367
  int rv = 0;
1368
  int idx = 0;
1369
1370
  // MDBGLOG("redir","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
1371
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1372
  out_uint32_le(s, self->DesiredAccess);
1373
  out_uint64_le(s, self->AllocationSize);
1374
  out_uint32_le(s, self->FileAttributes);
1375
  out_uint32_le(s, self->SharedAccess);
1376
  out_uint32_le(s, self->CreateDisposition);
1377
  out_uint32_le(s, self->CreateOptions);
1378
  out_uint32_le(s, self->PathLength);
1379
  if (self->PathLength > 0 && self->Path != NULL) {
1380
    for (idx = 0; idx < self->PathLength; idx++) {
1381
      out_uint8(s, self->Path[idx]);
1382
    }
1383
  }
1384
  else if (self->PathLength > 0) {
1385
    //out_uint8(s, 0x00);
1386
  }
1387
  // MDBGLOG("redir","INFO\t[%s()]: done.",__func__);
1388
1389
  return rv;
1390
}
1391
1392
int APP_CC
1393
get_DR_CREATE_REQ(DR_CREATE_REQ * self, struct stream * s) {
1394
  int rv = 0;
1395
  int idx = 0;
1396
1397
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1398
  in_uint32_le(s, self->DesiredAccess);
1399
  in_uint64_le(s, self->AllocationSize);
1400
  in_uint32_le(s, self->FileAttributes);
1401
  in_uint32_le(s, self->SharedAccess);
1402
  in_uint32_le(s, self->CreateDisposition);
1403
  in_uint32_le(s, self->CreateOptions);
1404
  in_uint32_le(s, self->PathLength);
1405
  for (idx = 0; idx < self->PathLength; idx++) {
1406
    in_uint8(s, self->Path[idx]);
1407
  }
1408
1409
  return rv;
1410
}
1411
1412
int APP_CC
1413
send_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ * self, struct stream * s) {
1414
  int rv = 0;
1415
1416
  send_DR_CREATE_REQ(&(self->DeviceCreateRequest), s);
1417
1418
  return rv;
1419
}
1420
1421
int APP_CC
1422
get_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ * self, struct stream * s) {
1423
  int rv = 0;
1424
1425
  get_DR_CREATE_REQ(&(self->DeviceCreateRequest), s);
1426
1427
  return rv;
1428
}
1429
1430
int APP_CC
1431
send_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ * self, struct stream * s) {
1432
  int rv = 0;
1433
1434
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1435
  out_uint32_le(s, self->FsInformationClass);
1436
  out_uint32_le(s, self->Length);
1437
  out_uint8a(s, self->Padding, 24);
1438
  if (self->Length > 0) {
1439
    out_uint8a(s, self->QueryVolumeBuffer.bytes, self->Length);
1440
  }
1441
1442
  return rv;
1443
}
1444
1445
int APP_CC
1446
get_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ * self, struct stream * s) {
1447
  int rv = 0;
1448
1449
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1450
  in_uint32_le(s, self->FsInformationClass);
1451
  in_uint32_le(s, self->Length);
1452
  in_uint8a(s, self->Padding, 24);
1453
  if (self->Length > 0) {
1454
    self->QueryVolumeBuffer.bytes = (BYTE *)g_malloc(sizeof(BYTE), 1);
1455
    in_uint8a(s, &(self->QueryVolumeBuffer.bytes), self->Length);
1456
  }
1457
1458
  return rv;
1459
}
1460
1461
int APP_CC
1462
send_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ * self, struct stream * s) {
1463
  int rv = 0;
1464
1465
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1466
  out_uint32_le(s, self->FsInformationClass);
1467
  out_uint8(s, self->InitialQuery);
1468
  out_uint32_le(s, self->PathLength);
1469
  out_uint8a(s, self->Padding, 23);
1470
  if (self->PathLength > 0) {
1471
    out_uint8a(s, self->Path, self->PathLength);
1472
  }
1473
1474
  return rv;
1475
}
1476
1477
int APP_CC
1478
get_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ * self, struct stream * s) {
1479
  int rv = 0;
1480
1481
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1482
  in_uint32_le(s, self->FsInformationClass);
1483
  in_uint8(s, self->InitialQuery);
1484
  in_uint32_le(s, self->PathLength);
1485
  in_uint8a(s, self->Padding, 23);
1486
  if (self->PathLength > 0) {
1487
    in_uint8a(s, self->Path, self->PathLength);
1488
  }
1489
1490
  return rv;
1491
}
1492
1493
int APP_CC
1494
send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ * self, struct stream * s) {
1495
  int rv = 0;
1496
1497
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1498
  out_uint8(s, self->WatchTree);
1499
  out_uint32_le(s, self->CompletionFilter);
1500
  out_uint8s(s, 27);
1501
1502
  return rv;
1503
}
1504
1505
int APP_CC
1506
get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ * self, struct stream * s) {
1507
  int rv = 0;
1508
1509
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1510
  in_uint8(s, self->WatchTree);
1511
  in_uint32_le(s, self->CompletionFilter);
1512
  in_uint8s(s, 27);
1513
1514
  return rv;
1515
}
1516
1517
int APP_CC
1518
send_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION * self, struct stream * s) {
1519
  int rv = 0;
1520
1521
  send_RDPDR_HEADER(&(self->Header), s);
1522
  out_uint32_le(s, self->DeviceId);
1523
  out_uint32_le(s, self->CompletionId);
1524
  out_uint32_le(s, self->IoStatus.Value);
1525
1526
  return rv;
1527
}
1528
1529
int APP_CC
1530
get_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION * self, struct stream * s) {
1531
  int rv = 0;
1532
1533
  get_RDPDR_HEADER(&(self->Header), s);
1534
  in_uint32_le(s, self->DeviceId);
1535
  in_uint32_le(s, self->CompletionId);
1536
  in_uint32_le(s, self->IoStatus.Value);
1537
1538
  return rv;
1539
}
1540
1541
int APP_CC
1542
send_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP * self, struct stream * s) {
1543
  int rv = 0;
1544
1545
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
1546
  out_uint32_le(s, self->Length);
1547
  if (self->Length > 0) {
1548
    out_uint8a(s, self->Buffer.bytes, self->Length);
1549
  }
1550
  //out_uint8(s, self->Padding);
1551
1552
  return rv;
1553
}
1554
1555
int APP_CC
1556
get_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP * self, struct stream * s) {
1557
  int rv = 0;
1558
1559
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
1560
  in_uint32_le(s, self->Length);
1561
  if (self->Length > 0) {
1562
    in_uint8a(s, self->Buffer.bytes, self->Length);
1563
  }
1564
  in_uint8(s, self->Padding);
1565
1566
  return rv;
1567
}
1568
1569
int APP_CC get_FILE_NAME_INFORMATION(FILE_NAME_INFORMATION * self, struct stream * s) {
1570
  int rv = 0;
1571
1572
  g_memset(self->FileName,0,sizeof(BYTE)*1024);
1573
  in_uint32_le(s, self->FileNameLength);
1574
  if (self->FileNameLength > 0) {
1575
    in_uint8a(s, (char *)self->FileName, self->FileNameLength);
1576
  }
1577
1578
  return rv;
1579
}
1580
1581
int APP_CC get_FILE_BASIC_INFORMATION(FILE_BASIC_INFORMATION * self, struct stream * s) {
1582
  int rv = 0;
1583
1584
  in_uint64_le(s, self->CreationTime);
1585
  in_uint64_le(s, self->LastAccessTime);
1586
  in_uint64_le(s, self->LastWriteTime);
1587
  in_uint64_le(s, self->ChangeTime);
1588
  in_uint32_le(s, self->FileAttributes);
1589
  in_uint32_le(s, self->Reserved);
1590
1591
  return rv;
1592
}
1593
1594
int APP_CC get_FILE_STANDARD_INFORMATION(FILE_STANDARD_INFORMATION * self, struct stream * s) {
1595
  int rv = 0;
1596
1597
  in_uint64_le(s, self->AllocationSize);
1598
  in_uint64_le(s, self->EndOfFile);
1599
  in_uint32_le(s, self->NumberOfLinks);
1600
  in_uint8(s, self->DeletePending);
1601
  in_uint8(s, self->Directory);
1602
  in_uint16_le(s, self->Reserved);
1603
1604
  return rv;
1605
}
1606
1607
int APP_CC get_FILE_ALL_INFORMATION(FILE_ALL_INFORMATION * self, struct stream * s) {
1608
  int rv = 0;
1609
1610
  get_FILE_BASIC_INFORMATION(&(self->BasicInformation), s);
1611
  get_FILE_STANDARD_INFORMATION(&(self->StandardInformation), s);
1612
  in_uint64_le(s, self->InternalInformation);
1613
  in_uint32_le(s, self->EaInformation);
1614
  in_uint32_le(s, self->AccessInformation);
1615
  in_uint64_le(s, self->PositionInformation);
1616
  in_uint32_le(s, self->ModeInformation);
1617
  in_uint32_le(s, self->AlignmentInformation);
1618
  get_FILE_NAME_INFORMATION(&(self->NameInformation), s);
1619
1620
  return rv;
1621
}
1622
1623
int APP_CC get_FILE_BOTH_DIR_INFORMATION(FILE_BOTH_DIR_INFORMATION * self, struct stream * s) {
1624
  int rv = 0;
1625
1626
  in_uint32_le(s, self->NextEntryOffset);
1627
  in_uint32_le(s, self->FileIndex);
1628
  in_uint64_le(s, self->CreationTime);
1629
  in_uint64_le(s, self->LastAccessTime);
1630
  in_uint64_le(s, self->LastWriteTime);
1631
  in_uint64_le(s, self->ChangeTime);
1632
  in_uint64_le(s, self->EndOfFile);
1633
  in_uint64_le(s, self->AllocationSize);
1634
  in_uint32_le(s, self->FileAttributes);
1635
  in_uint32_le(s, self->FileNameLength);
1636
  in_uint32_le(s, self->EaSize);
1637
  in_uint8(s, self->ShortNameLength);
1638
  //in_uint8(s, self->Reserved);
1639
  in_uint8a(s, self->ShortName, 24);
1640
  if (self->FileNameLength > 0) {
1641
    in_uint8a(s, (char *)(self->FileName), self->FileNameLength);
1642
  }
1643
1644
  return rv;
1645
}
1646
1647
int APP_CC send_FILE_NAME_INFORMATION(FILE_NAME_INFORMATION * self, struct stream * s) {
1648
  int rv = 0;
1649
1650
  out_uint32_le(s, self->FileNameLength);
1651
  if (self->FileNameLength > 0) {
1652
    out_uint8a(s, (char *)self->FileName, self->FileNameLength);
1653
  }
1654
1655
  return rv;
1656
}
1657
1658
int APP_CC send_FILE_BASIC_INFORMATION(FILE_BASIC_INFORMATION * self, struct stream * s) {
1659
  int rv = 0;
1660
1661
  out_uint64_le(s, self->CreationTime);
1662
  out_uint64_le(s, self->LastAccessTime);
1663
  out_uint64_le(s, self->LastWriteTime);
1664
  out_uint64_le(s, self->ChangeTime);
1665
  out_uint32_le(s, self->FileAttributes);
1666
  out_uint32_le(s, self->Reserved);
1667
1668
  return rv;
1669
}
1670
1671
int APP_CC send_FILE_STANDARD_INFORMATION(FILE_STANDARD_INFORMATION * self, struct stream * s) {
1672
  int rv = 0;
1673
1674
  out_uint64_le(s, self->AllocationSize);
1675
  out_uint64_le(s, self->EndOfFile);
1676
  out_uint32_le(s, self->NumberOfLinks);
1677
  out_uint8(s, self->DeletePending);
1678
  out_uint8(s, self->Directory);
1679
  out_uint16_le(s, self->Reserved);
1680
1681
  return rv;
1682
}
1683
1684
int APP_CC send_FILE_BOTH_DIR_INFORMATION(FILE_BOTH_DIR_INFORMATION * self, struct stream * s) {
1685
  int rv = 0;
1686
  char buf[512];
1687
  g_memset(buf,0,512);
1688
1689
  out_uint32_le(s, self->NextEntryOffset);
1690
  out_uint32_le(s, self->FileIndex);
1691
  out_uint64_le(s, self->CreationTime);
1692
  out_uint64_le(s, self->LastAccessTime);
1693
  out_uint64_le(s, self->LastWriteTime);
1694
  out_uint64_le(s, self->ChangeTime);
1695
  out_uint64_le(s, self->EndOfFile);
1696
  out_uint64_le(s, self->AllocationSize);
1697
  out_uint32_le(s, self->FileAttributes);
1698
  out_uint32_le(s, self->FileNameLength);
1699
  out_uint32_le(s, self->EaSize);
1700
  out_uint8(s, self->ShortNameLength);
1701
  //out_uint8(s, self->Reserved);
1702
  out_uint8a(s, self->ShortName, 24);
1703
  if (self->FileNameLength > 0) {
1704
    out_uint8a(s, (char *)(self->FileName), self->FileNameLength);
1705
  }
1706
1707
  if (1==2) {
1708
    // MDBGLOG("redir"," ----------- ");
1709
    // MDBGLOG("redir"," * NextEntryOffset = %u",self->NextEntryOffset);
1710
    // MDBGLOG("redir"," * FileIndex = %u",self->FileIndex);
1711
    // MDBGLOG("redir"," * CreationTime = %lu",self->CreationTime);
1712
    // MDBGLOG("redir"," * LastAccessTime = %lu",self->LastAccessTime);
1713
    // MDBGLOG("redir"," * LastWriteTime = %lu",self->LastWriteTime);
1714
    // MDBGLOG("redir"," * ChangeTime = %lu",self->ChangeTime);
1715
    // MDBGLOG("redir"," * EndOfFile = %lu",self->EndOfFile);
1716
    // MDBGLOG("redir"," * AllocationSize = %lu",self->AllocationSize);
1717
    // MDBGLOG("redir"," * FileAttributes = 0x%8.8x",self->FileAttributes);
1718
    // MDBGLOG("redir"," * FileNameLength = %u",self->FileNameLength);
1719
    // MDBGLOG("redir"," * EaSize = %u",self->EaSize);
1720
    // MDBGLOG("redir"," * ShortNameLength = %u",self->ShortNameLength);
1721
    //// MDBGLOG("redir"," * Reserved = %u",self->Reserved);
1722
    for (rv=0;rv<((self->ShortNameLength > 23) ? 23 : self->ShortNameLength);rv++) {
1723
      buf[rv] = self->ShortName[(rv * 2)];
1724
    }
1725
    //g_snprintf(buf,((self->ShortNameLength > 23) ? 23 : self->ShortNameLength),"%s",self->ShortName);
1726
    // MDBGLOG("redir"," * ShortName = %s\n", buf);
1727
    g_memset(buf,0,512);
1728
    for (rv=0;rv<((self->FileNameLength > 510) ? 510 : self->FileNameLength);rv++) {
1729
      buf[rv] = self->FileName[(rv * 2)];
1730
    }
1731
    //g_snprintf(buf,((self->FileNameLength > 510) ? 510 : self->FileNameLength),"%s",self->FileName);
1732
    // MDBGLOG("redir"," * FileName = %s\n", buf);
1733
    g_memset(buf,0,512);
1734
    rv = 0;
1735
  }
1736
1737
  return rv;
1738
}
1739
1740
/***/
1741
int APP_CC
1742
get_CAPABILITY_SET(CAPABILITY_SET * self, struct stream * s) {
1743
  int rv = 0;
1744
1745
  get_CAPABILITY_HEADER(&(self->Header), s);
1746
  if (self->Header.CapabilityLength > 0) {
1747
    self->capabilityData = (BYTE *)g_malloc(sizeof(BYTE) * self->Header.CapabilityLength, 1);
1748
    in_uint8a(s, self->capabilityData, self->Header.CapabilityLength);
1749
  }
1750
1751
  return rv;
1752
}
1753
1754
1755
/***/
1756
int APP_CC
1757
get_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE * self, struct stream * s) {
1758
  int rv = 0;
1759
1760
  in_uint32_le(s, self->DeviceType);
1761
  in_uint32_le(s, self->DeviceId);
1762
  in_uint8a(s, self->PreferredDosName, 8);
1763
  in_uint32_le(s, self->DeviceDataLength);
1764
  if (self->DeviceDataLength > 0) {
1765
    self->DeviceData = (BYTE *)g_malloc(sizeof(BYTE) * self->DeviceDataLength, 1);
1766
    in_uint8a(s, self->DeviceData, self->DeviceDataLength);
1767
  }
1768
1769
  return rv;
1770
}
1771
1772
1773
1774
/***/
1775
int APP_CC
1776
get_DR_CLOSE_REQ(DR_CLOSE_REQ * self, struct stream * s) {
1777
  int rv = 0;
1778
1779
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1780
  in_uint8a(s, self->Padding, 32);
1781
1782
  return rv;
1783
}
1784
1785
1786
1787
/***/
1788
int APP_CC
1789
get_DR_READ_REQ(DR_READ_REQ * self, struct stream * s) {
1790
  int rv = 0;
1791
1792
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1793
  in_uint32_le(s, self->Length);
1794
  in_uint64_le(s, self->Offset);
1795
  in_uint8a(s, self->Padding, 20);
1796
1797
  return rv;
1798
}
1799
1800
1801
1802
/***/
1803
int APP_CC
1804
get_DR_WRITE_REQ(DR_WRITE_REQ * self, struct stream * s) {
1805
  int rv = 0;
1806
1807
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1808
  in_uint32_le(s, self->Length);
1809
  in_uint64_le(s, self->Offset);
1810
  in_uint8a(s, self->Padding, 20);
1811
  if (self->Length > 0) {
1812
    self->WriteData = (BYTE *)g_malloc(sizeof(BYTE) * self->Length, 1);
1813
    in_uint8a(s, self->WriteData, self->Length);
1814
  }
1815
1816
  return rv;
1817
}
1818
1819
1820
1821
/***/
1822
int APP_CC
1823
get_DR_CONTROL_REQ(DR_CONTROL_REQ * self, struct stream * s) {
1824
  int rv = 0;
1825
1826
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
1827
  in_uint32_le(s, self->OutputBufferLength);
1828
  in_uint32_le(s, self->InputBufferLength);
1829
  in_uint32_le(s, self->IoControlCode);
1830
  in_uint8a(s, self->Padding, 20);
1831
  if (self->InputBufferLength > 0) {
1832
    self->InputBuffer = (BYTE *)g_malloc(sizeof(BYTE) * self->InputBufferLength, 1);
1833
    in_uint8a(s, self->InputBuffer, self->InputBufferLength);
1834
  }
1835
1836
  return rv;
1837
}
1838
1839
1840
1841
/***/
1842
int APP_CC
1843
get_DR_CREATE_RSP(DR_CREATE_RSP * self, struct stream * s) {
1844
  int rv = 0;
1845
1846
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
1847
  in_uint32_le(s, self->FileId);
1848
  in_uint8(s, self->Information);
1849
1850
  return rv;
1851
}
1852
1853
1854
1855
/***/
1856
int APP_CC
1857
get_DR_CLOSE_RSP(DR_CLOSE_RSP * self, struct stream * s) {
1858
  int rv = 0;
1859
1860
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
1861
  in_uint8a(s, self->Padding, 5);
1862
1863
  return rv;
1864
}
1865
1866
1867
1868
/***/
1869
int APP_CC
1870
get_DR_READ_RSP(DR_READ_RSP * self, struct stream * s) {
1871
  int rv = 0;
1872
1873
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
1874
  in_uint32_le(s, self->Length);
1875
  if (self->Length > 0) {
1876
    if (self->ReadData == NULL) {
1877
      self->ReadData = (BYTE *)g_malloc(sizeof(BYTE) * self->Length, 1);
1878
    }
1879
    in_uint8a(s, self->ReadData, self->Length);
1880
  }
1881
1882
  return rv;
1883
}
1884
1885
1886
1887
/***/
1888
int APP_CC
1889
get_DR_WRITE_RSP(DR_WRITE_RSP * self, struct stream * s) {
1890
  int rv = 0;
1891
1892
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
1893
  in_uint32_le(s, self->Length);
1894
  in_uint8(s, self->Padding);
1895
1896
  return rv;
1897
}
1898
1899
1900
1901
/***/
1902
int APP_CC
1903
get_DR_CONTROL_RSP(DR_CONTROL_RSP * self, struct stream * s) {
1904
  int rv = 0;
1905
1906
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
1907
  in_uint32_le(s, self->OutputBufferLength);
1908
  if (self->OutputBufferLength > 0) {
1909
    self->OutputBuffer = (BYTE *)g_malloc(sizeof(BYTE) * self->OutputBufferLength, 1);
1910
    in_uint8a(s, self->OutputBuffer, self->OutputBufferLength);
1911
  }
1912
1913
  return rv;
1914
}
1915
1916
1917
1918
/***/
1919
int APP_CC
1920
get_RDP_LOCK_INFO(RDP_LOCK_INFO * self, struct stream * s) {
1921
  int rv = 0;
1922
1923
  in_uint64_le(s, self->Length);
1924
  in_uint64_le(s, self->Offset);
1925
1926
  return rv;
1927
}
1928
1929
1930
1931
/***/
1932
int APP_CC
1933
get_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP * self, struct stream * s) {
1934
  int rv = 0;
1935
1936
  get_RDPDR_HEADER(&(self->Header), s);
1937
  in_uint32_le(s, self->DeviceId);
1938
  in_uint32_le(s, self->ResultCode);
1939
1940
  return rv;
1941
}
1942
1943
1944
1945
/***/
1946
int APP_CC
1947
get_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ * self, struct stream * s) {
1948
  int rv = 0;
1949
1950
  get_RDPDR_HEADER(&(self->Header), s);
1951
  in_uint16_le(s, self->VersionMajor);
1952
  in_uint16_le(s, self->VersionMinor);
1953
  in_uint32_le(s, self->ClientId);
1954
1955
  return rv;
1956
}
1957
1958
1959
1960
/***/
1961
int APP_CC
1962
get_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM * self, struct stream * s) {
1963
  int rv = 0;
1964
1965
  get_RDPDR_HEADER(&(self->Header), s);
1966
  in_uint16_le(s, self->VersionMajor);
1967
  in_uint16_le(s, self->VersionMinor);
1968
  in_uint32_le(s, self->ClientId);
1969
1970
  return rv;
1971
}
1972
1973
1974
1975
/***/
1976
int APP_CC
1977
get_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ * self, struct stream * s) {
1978
  int rv = 0;
1979
  int idx = 0;
1980
1981
  get_RDPDR_HEADER(&(self->Header), s);
1982
  in_uint16_le(s, self->numCapabilities);
1983
  in_uint16_le(s, self->Padding);
1984
  if (self->numCapabilities > 0) {
1985
    self->CapabilityMessage = (CAPABILITY_SET *)g_malloc(sizeof(CAPABILITY_SET) * self->numCapabilities, 1);
1986
    for (idx = 0; idx < self->numCapabilities; idx++) {
1987
      get_CAPABILITY_HEADER(&(self->CapabilityMessage[idx].Header), s);
1988
      if (self->CapabilityMessage[idx].Header.CapabilityLength > 0) {
1989
	self->CapabilityMessage[idx].capabilityData = (BYTE *)g_malloc(sizeof(BYTE) * self->CapabilityMessage[idx].Header.CapabilityLength, 1);
1990
	in_uint8a(s, self->CapabilityMessage[idx].capabilityData, self->CapabilityMessage[idx].Header.CapabilityLength);
1991
      }
1992
    }
1993
  }
1994
1995
  return rv;
1996
}
1997
1998
1999
2000
/***/
2001
int APP_CC
2002
get_GENERAL_CAPS_SET(GENERAL_CAPS_SET * self, struct stream * s) {
2003
  int rv = 0;
2004
2005
  get_CAPABILITY_HEADER(&(self->Header), s);
2006
  in_uint32_le(s, self->osType);
2007
  in_uint32_le(s, self->osVersion);
2008
  in_uint16_le(s, self->protocolMajorVersion);
2009
  in_uint16_le(s, self->protocolMinorVersion);
2010
  in_uint32_le(s, self->ioCode1);
2011
  in_uint32_le(s, self->ioCode2);
2012
  in_uint32_le(s, self->extendedPDU);
2013
  in_uint32_le(s, self->extraFlags1);
2014
  in_uint32_le(s, self->extraFlags2);
2015
  in_uint32_le(s, self->SpecialTypeDeviceCap);
2016
2017
  return rv;
2018
}
2019
2020
2021
2022
/***/
2023
int APP_CC
2024
get_PRINTER_CAPS_SET(PRINTER_CAPS_SET * self, struct stream * s) {
2025
  int rv = 0;
2026
2027
  get_CAPABILITY_HEADER(&(self->Header), s);
2028
2029
  return rv;
2030
}
2031
2032
2033
2034
/***/
2035
int APP_CC
2036
get_PORT_CAPS_SET(PORT_CAPS_SET * self, struct stream * s) {
2037
  int rv = 0;
2038
2039
  get_CAPABILITY_HEADER(&(self->Header), s);
2040
2041
  return rv;
2042
}
2043
2044
2045
2046
/***/
2047
int APP_CC
2048
get_DRIVE_CAPS_SET(DRIVE_CAPS_SET * self, struct stream * s) {
2049
  int rv = 0;
2050
2051
  get_CAPABILITY_HEADER(&(self->Header), s);
2052
2053
  return rv;
2054
}
2055
2056
2057
2058
/***/
2059
int APP_CC
2060
get_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET * self, struct stream * s) {
2061
  int rv = 0;
2062
2063
  get_CAPABILITY_HEADER(&(self->Header), s);
2064
2065
  return rv;
2066
}
2067
2068
2069
2070
/***/
2071
int APP_CC
2072
get_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ * self, struct stream * s) {
2073
  int rv = 0;
2074
  int idx = 0;
2075
2076
  get_RDPDR_HEADER(&(self->Header), s);
2077
  in_uint32_le(s, self->DeviceCount);
2078
  if (self->DeviceCount > 0) {
2079
    self->DeviceList = (DEVICE_ANNOUNCE *)g_malloc(sizeof(DEVICE_ANNOUNCE) * self->DeviceCount, 1);
2080
    for (idx = 0; idx < self->DeviceCount; idx++) {
2081
      get_DEVICE_ANNOUNCE(&(self->DeviceList[idx]), s);
2082
    }
2083
  }
2084
2085
  return rv;
2086
}
2087
2088
2089
2090
/***/
2091
int APP_CC
2092
get_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE * self, struct stream * s) {
2093
  int rv = 0;
2094
  int idx = 0;
2095
2096
  get_RDPDR_HEADER(&(self->Header), s);
2097
  in_uint32_le(s, self->DeviceCount);
2098
  if (self->DeviceCount > 0) {
2099
    self->DeviceList = (DEVICE_ANNOUNCE **)g_malloc(sizeof(size_t) * self->DeviceCount, 1);
2100
    for (idx = 0; idx < self->DeviceCount; idx++) {
2101
      self->DeviceList[idx] = (DEVICE_ANNOUNCE *)g_malloc(sizeof(DEVICE_ANNOUNCE), 1);
2102
      get_DEVICE_ANNOUNCE(self->DeviceList[idx], s);
2103
    }
2104
  }
2105
2106
  return rv;
2107
}
2108
2109
2110
2111
/***/
2112
int APP_CC
2113
get_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE * self, struct stream * s) {
2114
  int rv = 0;
2115
  int idx = 0;
2116
2117
  get_RDPDR_HEADER(&(self->Header), s);
2118
  in_uint32_le(s, self->DeviceCount);
2119
  if (self->DeviceCount > 0) {
2120
    self->DeviceIds = (DWORD *)g_malloc(sizeof(DWORD) * self->DeviceCount, 1);
2121
    for (idx = 0; idx < self->DeviceCount; idx++) {
2122
      in_uint32_le(s, self->DeviceIds[idx]);
2123
    }
2124
  }
2125
2126
  return rv;
2127
}
2128
2129
2130
2131
/***/
2132
int APP_CC
2133
get_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST * self, struct stream * s) {
2134
  int rv = 0;
2135
2136
  //get_(&(self->Header), s);
2137
2138
  return rv;
2139
}
2140
2141
2142
2143
/***/
2144
int APP_CC
2145
get_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ * self, struct stream * s) {
2146
  int rv = 0;
2147
2148
  get_DR_CLOSE_REQ(&(self->DeviceCloseRequest), s);
2149
2150
  return rv;
2151
}
2152
2153
2154
2155
/***/
2156
int APP_CC
2157
get_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ * self, struct stream * s) {
2158
  int rv = 0;
2159
2160
  get_DR_READ_REQ(&(self->DeviceReadRequest), s);
2161
2162
  return rv;
2163
}
2164
2165
2166
2167
/***/
2168
int APP_CC
2169
get_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ * self, struct stream * s) {
2170
  int rv = 0;
2171
2172
  get_DR_WRITE_REQ(&(self->DeviceWriteRequest), s);
2173
2174
  return rv;
2175
}
2176
2177
2178
2179
/***/
2180
int APP_CC
2181
get_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ * self, struct stream * s) {
2182
  int rv = 0;
2183
2184
  get_DR_CONTROL_REQ(&(self->Header), s);
2185
  return rv;
2186
}
2187
2188
2189
2190
/***/
2191
int APP_CC
2192
get_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ * self, struct stream * s) {
2193
  int rv = 0;
2194
2195
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2196
  in_uint32_le(s, self->FsInformationClass);
2197
  in_uint32_le(s, self->Length);
2198
  in_uint8a(s, self->Padding, 24);
2199
  if (self->Length > 0) {
2200
    self->SetVolumeBuffer = (BYTE *)g_malloc(sizeof(BYTE) * self->Length, 1);
2201
    in_uint8a(s, self->SetVolumeBuffer, self->Length);
2202
  }
2203
2204
  return rv;
2205
}
2206
2207
2208
/***/
2209
int APP_CC
2210
get_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ * self, struct stream * s) {
2211
  int rv = 0;
2212
2213
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2214
  in_uint32_le(s, self->FsInformationClass);
2215
  in_uint32_le(s, self->Length);
2216
  in_uint8a(s, self->Padding, 24);
2217
  if (self->Length > 0) {
2218
    in_uint8a(s, self->QueryBuffer.bytes, ((((int)(self->Length)) > (int)(sizeof(FILE_BASIC_INFORMATION))) ? (int)sizeof(FILE_BASIC_INFORMATION) : ((int)(self->Length))));
2219
  }
2220
2221
  return rv;
2222
}
2223
2224
2225
2226
/***/
2227
int APP_CC
2228
get_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ * self, struct stream * s) {
2229
  int rv = 0;
2230
2231
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2232
  in_uint32_le(s, self->FsInformationClass);
2233
  in_uint32_le(s, self->Length);
2234
  in_uint8a(s, self->Padding, 24);
2235
  if (self->Length > 0) {
2236
    //self->SetBuffer = (BYTE *)g_malloc(sizeof(BYTE) * self->Length, 1);
2237
    in_uint8a(s, self->SetBuffer.bytes, self->Length);
2238
  }
2239
2240
  return rv;
2241
}
2242
2243
2244
/***/
2245
int APP_CC
2246
get_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION * self, struct stream * s) {
2247
  int rv = 0;
2248
2249
  in_uint8(s, self->ReplaceIfExists);
2250
  in_uint8(s, self->RootDirectory);
2251
  in_uint32_le(s, self->FileNameLength);
2252
  if (self->FileNameLength > 0) {
2253
    in_uint8a(s, self->FileName, self->FileNameLength);
2254
  }
2255
2256
  return rv;
2257
}
2258
2259
2260
2261
/***/
2262
int APP_CC
2263
get_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ * self, struct stream * s) {
2264
  int rv = 0;
2265
  int idx = 0;
2266
2267
  get_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2268
  in_uint32_le(s, self->Operation);
2269
  in_uint32_le(s, self->F);
2270
  in_uint32_le(s, self->NumLocks);
2271
  in_uint8a(s, self->Padding2, 20);
2272
  if (self->NumLocks > 0) {
2273
    self->Locks = (RDP_LOCK_INFO *)g_malloc(sizeof(RDP_LOCK_INFO) * self->NumLocks, 1);
2274
    for (idx = 0; idx < self->NumLocks; idx++) {
2275
      get_RDP_LOCK_INFO(&(self->Locks[idx]), s);
2276
    }
2277
  }
2278
2279
  return rv;
2280
}
2281
2282
2283
2284
/***/
2285
int APP_CC
2286
get_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION * self, struct stream * s) {
2287
  int rv = 0;
2288
2289
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoResponse), s);
2290
2291
  return rv;
2292
}
2293
2294
2295
2296
/***/
2297
int APP_CC
2298
get_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP * self, struct stream * s) {
2299
  int rv = 0;
2300
2301
  get_DR_CREATE_RSP(&(self->DeviceCreateResponse), s);
2302
2303
  return rv;
2304
}
2305
2306
2307
2308
/***/
2309
int APP_CC
2310
get_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP * self, struct stream * s) {
2311
  int rv = 0;
2312
2313
  get_DR_CLOSE_RSP(&(self->DeviceCloseResponse), s);
2314
2315
  return rv;
2316
}
2317
2318
2319
/***/
2320
int APP_CC
2321
get_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP * self, struct stream * s) {
2322
  int rv = 0;
2323
2324
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2325
  in_uint32_le(s, self->Length);
2326
  if (self->Length > 0) {
2327
    //self->Buffer = (BYTE *)g_malloc(sizeof(BYTE) * self->Length, 1);
2328
    in_uint8a(s, self->Buffer.bytes, self->Length);
2329
  }
2330
  //in_uint8(s, self->Padding);
2331
2332
  return rv;
2333
}
2334
2335
2336
2337
/***/
2338
int APP_CC
2339
get_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP * self, struct stream * s) {
2340
  int rv = 0;
2341
2342
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2343
  in_uint32_le(s, self->Length);
2344
2345
  return rv;
2346
}
2347
2348
2349
2350
/***/
2351
int APP_CC
2352
get_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP * self, struct stream * s) {
2353
  int rv = 0;
2354
2355
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2356
  in_uint32_le(s, self->Length);
2357
  if (self->Length > 0 && self->Length < MAX_STREAM) {
2358
    in_uint8a(s, self->Buffer.bytes, ((self->Length > sizeof(union _DrDriveQueryInformationRsp_Buffer)) ? sizeof(union _DrDriveQueryInformationRsp_Buffer) : self->Length));
2359
  }
2360
2361
  return rv;
2362
}
2363
2364
2365
2366
/***/
2367
int APP_CC
2368
get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP * self, struct stream * s) {
2369
  int rv = 0;
2370
2371
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2372
  in_uint32_le(s, self->Length);
2373
  if (self->Length > 0) {
2374
    self->Buffer = (BYTE *)g_malloc(sizeof(BYTE) * self->Length, 1);
2375
    in_uint8a(s, self->Buffer, self->Length);
2376
  }
2377
  //in_uint8(s, self->Padding);
2378
2379
  return rv;
2380
}
2381
2382
2383
2384
/***/
2385
int APP_CC
2386
get_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP * self, struct stream * s) {
2387
  int rv = 0;
2388
2389
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2390
  in_uint8a(s, self->Padding, 5);
2391
2392
  return rv;
2393
}
2394
2395
2396
/***/
2397
int APP_CC
2398
send_CAPABILITY_SET(CAPABILITY_SET * self, struct stream * s) {
2399
  int rv = 0;
2400
2401
  send_CAPABILITY_HEADER(&(self->Header), s);
2402
  if (self->Header.CapabilityLength > 0) {
2403
    out_uint8a(s, self->capabilityData, self->Header.CapabilityLength);
2404
  }
2405
2406
  return rv;
2407
}
2408
2409
2410
/***/
2411
int APP_CC
2412
send_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE * self, struct stream * s) {
2413
  int rv = 0;
2414
2415
  out_uint32_le(s, self->DeviceType);
2416
  out_uint32_le(s, self->DeviceId);
2417
  out_uint8a(s, self->PreferredDosName, 8);
2418
  out_uint32_le(s, self->DeviceDataLength);
2419
  if (self->DeviceDataLength > 0) {
2420
    out_uint8a(s, self->DeviceData, self->DeviceDataLength);
2421
  }
2422
2423
  return rv;
2424
}
2425
2426
2427
2428
/***/
2429
int APP_CC
2430
send_DR_CLOSE_REQ(DR_CLOSE_REQ * self, struct stream * s) {
2431
  int rv = 0;
2432
2433
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2434
  out_uint8a(s, self->Padding, 32);
2435
2436
  return rv;
2437
}
2438
2439
2440
2441
/***/
2442
int APP_CC
2443
send_DR_READ_REQ(DR_READ_REQ * self, struct stream * s) {
2444
  int rv = 0;
2445
  unsigned char padding[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2446
2447
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2448
  out_uint32_le(s, self->Length);
2449
  out_uint64_le(s, self->Offset);
2450
  //out_uint8a(s, self->Padding, 20);
2451
  out_uint8a(s, padding, 20);
2452
2453
  return rv;
2454
}
2455
2456
2457
2458
/***/
2459
int APP_CC
2460
send_DR_WRITE_REQ(DR_WRITE_REQ * self, struct stream * s) {
2461
  int rv = 0;
2462
2463
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2464
  out_uint32_le(s, self->Length);
2465
  out_uint64_le(s, self->Offset);
2466
  out_uint8a(s, self->Padding, 20);
2467
  if (self->Length > 0) {
2468
    out_uint8a(s, self->WriteData, self->Length);
2469
  }
2470
2471
  return rv;
2472
}
2473
2474
2475
2476
/***/
2477
int APP_CC
2478
send_DR_CONTROL_REQ(DR_CONTROL_REQ * self, struct stream * s) {
2479
  int rv = 0;
2480
2481
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2482
  out_uint32_le(s, self->OutputBufferLength);
2483
  out_uint32_le(s, self->InputBufferLength);
2484
  out_uint32_le(s, self->IoControlCode);
2485
  out_uint8a(s, self->Padding, 20);
2486
  if (self->InputBufferLength > 0) {
2487
    out_uint8a(s, self->InputBuffer, self->InputBufferLength);
2488
  }
2489
2490
  return rv;
2491
}
2492
2493
2494
2495
/***/
2496
int APP_CC
2497
send_DR_CREATE_RSP(DR_CREATE_RSP * self, struct stream * s) {
2498
  int rv = 0;
2499
2500
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2501
  out_uint32_le(s, self->FileId);
2502
  out_uint8(s, self->Information);
2503
2504
  return rv;
2505
}
2506
2507
2508
2509
/***/
2510
int APP_CC
2511
send_DR_CLOSE_RSP(DR_CLOSE_RSP * self, struct stream * s) {
2512
  int rv = 0;
2513
2514
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2515
  out_uint8a(s, self->Padding, 5);
2516
2517
  return rv;
2518
}
2519
2520
2521
2522
/***/
2523
int APP_CC
2524
send_DR_READ_RSP(DR_READ_RSP * self, struct stream * s) {
2525
  int rv = 0;
2526
2527
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2528
  out_uint32_le(s, self->Length);
2529
  if (self->Length > 0 && self->ReadData != NULL) {
2530
    out_uint8a(s, self->ReadData, self->Length);
2531
  }
2532
2533
  return rv;
2534
}
2535
2536
2537
2538
/***/
2539
int APP_CC
2540
send_DR_WRITE_RSP(DR_WRITE_RSP * self, struct stream * s) {
2541
  int rv = 0;
2542
2543
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2544
  out_uint32_le(s, self->Length);
2545
  out_uint8(s, self->Padding);
2546
2547
  return rv;
2548
}
2549
2550
2551
2552
/***/
2553
int APP_CC
2554
send_DR_CONTROL_RSP(DR_CONTROL_RSP * self, struct stream * s) {
2555
  int rv = 0;
2556
2557
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2558
  out_uint32_le(s, self->OutputBufferLength);
2559
  if (self->OutputBufferLength > 0) {
2560
    out_uint8a(s, self->OutputBuffer, self->OutputBufferLength);
2561
  }
2562
2563
  return rv;
2564
}
2565
2566
2567
2568
/***/
2569
int APP_CC
2570
send_RDP_LOCK_INFO(RDP_LOCK_INFO * self, struct stream * s) {
2571
  int rv = 0;
2572
2573
  out_uint64_le(s, self->Length);
2574
  out_uint64_le(s, self->Offset);
2575
2576
  return rv;
2577
}
2578
2579
2580
2581
/***/
2582
int APP_CC
2583
send_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP * self, struct stream * s) {
2584
  int rv = 0;
2585
2586
  send_RDPDR_HEADER(&(self->Header), s);
2587
  out_uint32_le(s, self->DeviceId);
2588
  out_uint32_le(s, self->ResultCode);
2589
2590
  return rv;
2591
}
2592
2593
2594
/***/
2595
int APP_CC
2596
send_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM * self, struct stream * s) {
2597
  int rv = 0;
2598
2599
  send_RDPDR_HEADER(&(self->Header), s);
2600
  out_uint16_le(s, self->VersionMajor);
2601
  out_uint16_le(s, self->VersionMinor);
2602
  out_uint32_le(s, self->ClientId);
2603
2604
  return rv;
2605
}
2606
2607
2608
2609
/***/
2610
int APP_CC
2611
send_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ * self, struct stream * s) {
2612
  int rv = 0;
2613
  int idx = 0;
2614
2615
  send_RDPDR_HEADER(&(self->Header), s);
2616
  out_uint16_le(s, self->numCapabilities);
2617
  out_uint16_le(s, self->Padding);
2618
  if (self->numCapabilities > 0) {
2619
    for (idx = 0; idx < self->numCapabilities; idx++) {
2620
      send_CAPABILITY_HEADER(&(self->CapabilityMessage[idx].Header), s);
2621
      if (self->CapabilityMessage[idx].Header.CapabilityLength > 0) {
2622
	out_uint8a(s, self->CapabilityMessage[idx].capabilityData, self->CapabilityMessage[idx].Header.CapabilityLength);
2623
      }
2624
    }
2625
  }
2626
2627
  return rv;
2628
}
2629
2630
2631
2632
/***/
2633
int APP_CC
2634
send_GENERAL_CAPS_SET(GENERAL_CAPS_SET * self, struct stream * s) {
2635
  int rv = 0;
2636
2637
  send_CAPABILITY_HEADER(&(self->Header), s);
2638
  out_uint32_le(s, self->osType);
2639
  out_uint32_le(s, self->osVersion);
2640
  out_uint16_le(s, self->protocolMajorVersion);
2641
  out_uint16_le(s, self->protocolMinorVersion);
2642
  out_uint32_le(s, self->ioCode1);
2643
  out_uint32_le(s, self->ioCode2);
2644
  out_uint32_le(s, self->extendedPDU);
2645
  out_uint32_le(s, self->extraFlags1);
2646
  out_uint32_le(s, self->extraFlags2);
2647
  out_uint32_le(s, self->SpecialTypeDeviceCap);
2648
2649
  return rv;
2650
}
2651
2652
2653
2654
/***/
2655
int APP_CC
2656
send_PRINTER_CAPS_SET(PRINTER_CAPS_SET * self, struct stream * s) {
2657
  int rv = 0;
2658
2659
  send_CAPABILITY_HEADER(&(self->Header), s);
2660
2661
  return rv;
2662
}
2663
2664
2665
2666
/***/
2667
int APP_CC
2668
send_PORT_CAPS_SET(PORT_CAPS_SET * self, struct stream * s) {
2669
  int rv = 0;
2670
2671
  send_CAPABILITY_HEADER(&(self->Header), s);
2672
2673
  return rv;
2674
}
2675
2676
2677
2678
/***/
2679
int APP_CC
2680
send_DRIVE_CAPS_SET(DRIVE_CAPS_SET * self, struct stream * s) {
2681
  int rv = 0;
2682
2683
  send_CAPABILITY_HEADER(&(self->Header), s);
2684
2685
  return rv;
2686
}
2687
2688
2689
2690
/***/
2691
int APP_CC
2692
send_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET * self, struct stream * s) {
2693
  int rv = 0;
2694
2695
  send_CAPABILITY_HEADER(&(self->Header), s);
2696
2697
  return rv;
2698
}
2699
2700
2701
2702
/***/
2703
int APP_CC
2704
send_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ * self, struct stream * s) {
2705
  int rv = 0;
2706
  int idx = 0;
2707
2708
  send_RDPDR_HEADER(&(self->Header), s);
2709
  out_uint32_le(s, self->DeviceCount);
2710
  if (self->DeviceCount > 0) {
2711
    for (idx = 0; idx < self->DeviceCount; idx++) {
2712
      send_DEVICE_ANNOUNCE(&(self->DeviceList[idx]), s);
2713
    }
2714
  }
2715
2716
  return rv;
2717
}
2718
2719
2720
2721
/***/
2722
int APP_CC
2723
send_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE * self, struct stream * s) {
2724
  int rv = 0;
2725
  int idx = 0;
2726
2727
  send_RDPDR_HEADER(&(self->Header), s);
2728
  out_uint32_le(s, self->DeviceCount);
2729
  if (self->DeviceCount > 0) {
2730
    for (idx = 0; idx < self->DeviceCount; idx++) {
2731
      send_DEVICE_ANNOUNCE(self->DeviceList[idx], s);
2732
    }
2733
  }
2734
2735
  return rv;
2736
}
2737
2738
2739
2740
/***/
2741
int APP_CC
2742
send_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE * self, struct stream * s) {
2743
  int rv = 0;
2744
  int idx = 0;
2745
2746
  send_RDPDR_HEADER(&(self->Header), s);
2747
  out_uint32_le(s, self->DeviceCount);
2748
  if (self->DeviceCount > 0) {
2749
    for (idx = 0; idx < self->DeviceCount; idx++) {
2750
      out_uint32_le(s, self->DeviceIds[idx]);
2751
    }
2752
  }
2753
2754
  return rv;
2755
}
2756
2757
2758
2759
/***/
2760
int APP_CC
2761
send_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST * self, struct stream * s) {
2762
  int rv = 0;
2763
2764
  send_DR_DEVICE_IOREQUEST(&(self->Header), s);
2765
2766
  return rv;
2767
}
2768
2769
2770
2771
/***/
2772
int APP_CC
2773
send_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ * self, struct stream * s) {
2774
  int rv = 0;
2775
2776
  send_DR_CLOSE_REQ(&(self->DeviceCloseRequest), s);
2777
2778
  return rv;
2779
}
2780
2781
2782
2783
/***/
2784
int APP_CC
2785
send_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ * self, struct stream * s) {
2786
  int rv = 0;
2787
2788
  send_DR_READ_REQ(&(self->DeviceReadRequest), s);
2789
2790
  return rv;
2791
}
2792
2793
2794
2795
/***/
2796
int APP_CC
2797
send_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ * self, struct stream * s) {
2798
  int rv = 0;
2799
2800
  send_DR_WRITE_REQ(&(self->DeviceWriteRequest), s);
2801
2802
  return rv;
2803
}
2804
2805
2806
2807
/***/
2808
int APP_CC
2809
send_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ * self, struct stream * s) {
2810
  int rv = 0;
2811
2812
  send_DR_CONTROL_REQ(&(self->Header), s);
2813
  return rv;
2814
}
2815
2816
2817
2818
/***/
2819
int APP_CC
2820
send_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ * self, struct stream * s) {
2821
  int rv = 0;
2822
2823
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2824
  out_uint32_le(s, self->FsInformationClass);
2825
  out_uint32_le(s, self->Length);
2826
  out_uint8a(s, self->Padding, 24);
2827
  if (self->Length > 0) {
2828
    out_uint8a(s, self->SetVolumeBuffer, self->Length);
2829
  }
2830
2831
  return rv;
2832
}
2833
2834
2835
/***/
2836
int APP_CC
2837
send_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ * self, struct stream * s) {
2838
  int rv = 0;
2839
2840
  if (self == NULL || s == NULL) {
2841
    // MDBGLOG("redir","ERROR [send_DR_DRIVE_QUERY_INFORMATION_REQ()]: null pointer");
2842
    rv = -ENOMEM;
2843
  }
2844
  else {
2845
    send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2846
    out_uint32_le(s, self->FsInformationClass);
2847
    out_uint32_le(s, self->Length);
2848
    out_uint8a(s, self->Padding, 24);
2849
    if (self->Length > 0) {
2850
      out_uint8a(s, self->QueryBuffer.bytes, self->Length);
2851
    }
2852
  }
2853
2854
  return rv;
2855
}
2856
2857
2858
2859
/***/
2860
int APP_CC
2861
send_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ * self, struct stream * s) {
2862
  int rv = 0;
2863
2864
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2865
  out_uint32_le(s, self->FsInformationClass);
2866
  out_uint32_le(s, self->Length);
2867
  out_uint8a(s, self->Padding, 24);
2868
  if (self->Length > 0) {
2869
    out_uint8a(s, self->SetBuffer.bytes, self->Length);
2870
  }
2871
2872
  return rv;
2873
}
2874
2875
2876
/***/
2877
int APP_CC send_DR_DRIVE_SET_INFORMATION_REQ_rename(DR_DRIVE_SET_INFORMATION_REQ * self, struct stream * s) {
2878
  int rv = 0;
2879
2880
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2881
  out_uint32_le(s, self->FsInformationClass);
2882
  out_uint32_le(s, self->Length);
2883
  out_uint8a(s, self->Padding, 24);
2884
  send_RDP_FILE_RENAME_INFORMATION(&(self->SetBuffer.RenameInformation), s);
2885
  //if (self->Length > 0) {
2886
  //  out_uint8a(s, self->SetBuffer.bytes, self->Length);
2887
  //}
2888
2889
  return rv;
2890
}
2891
2892
2893
/***/
2894
int APP_CC
2895
send_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION * self, struct stream * s) {
2896
  int rv = 0;
2897
2898
  out_uint8(s, self->ReplaceIfExists);
2899
  out_uint8(s, self->RootDirectory);
2900
  out_uint32_le(s, self->FileNameLength);
2901
  if (self->FileNameLength > 0) {
2902
    out_uint8a(s, self->FileName, self->FileNameLength);
2903
  }
2904
2905
  return rv;
2906
}
2907
2908
2909
2910
/***/
2911
int APP_CC
2912
send_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ * self, struct stream * s) {
2913
  int rv = 0;
2914
  int idx = 0;
2915
2916
  send_DR_DEVICE_IOREQUEST(&(self->DeviceIoRequest), s);
2917
  out_uint32_le(s, self->Operation);
2918
  out_uint32_le(s, self->F);
2919
  out_uint32_le(s, self->NumLocks);
2920
  out_uint8a(s, self->Padding2, 20);
2921
  if (self->NumLocks > 0) {
2922
    for (idx = 0; idx < self->NumLocks; idx++) {
2923
      send_RDP_LOCK_INFO(&(self->Locks[idx]), s);
2924
    }
2925
  }
2926
2927
  return rv;
2928
}
2929
2930
2931
2932
/***/
2933
int APP_CC
2934
send_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION * self, struct stream * s) {
2935
  int rv = 0;
2936
2937
  if (self == NULL || s == NULL) {
2938
    rv = -1;
2939
  }
2940
  else {
2941
    send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoResponse), s);
2942
  }
2943
2944
  return rv;
2945
}
2946
2947
2948
2949
/***/
2950
int APP_CC
2951
send_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP * self, struct stream * s) {
2952
  int rv = 0;
2953
2954
  if (self == NULL || s == NULL) {
2955
    rv = -1;
2956
  }
2957
  else {
2958
    send_DR_CREATE_RSP(&(self->DeviceCreateResponse), s);
2959
  }
2960
2961
  return rv;
2962
}
2963
2964
2965
2966
/***/
2967
int APP_CC
2968
send_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP * self, struct stream * s) {
2969
  int rv = 0;
2970
2971
  if (self == NULL || s == NULL) {
2972
    rv = -1;
2973
  }
2974
  else {
2975
    send_DR_CLOSE_RSP(&(self->DeviceCloseResponse), s);
2976
  }
2977
2978
  return rv;
2979
}
2980
2981
2982
/***/
2983
int APP_CC
2984
send_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP * self, struct stream * s) {
2985
  int rv = 0;
2986
2987
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
2988
  out_uint32_le(s, self->Length);
2989
  if (self->Length > 0) {
2990
    out_uint8a(s, self->Buffer.bytes, self->Length);
2991
  }
2992
  //out_uint8(s, self->Padding);
2993
2994
  return rv;
2995
}
2996
2997
2998
2999
/***/
3000
int APP_CC
3001
send_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP * self, struct stream * s) {
3002
  int rv = 0;
3003
3004
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
3005
  out_uint32_le(s, self->Length);
3006
3007
  return rv;
3008
}
3009
3010
3011
3012
/***/
3013
int APP_CC
3014
send_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP * self, struct stream * s) {
3015
  int rv = 0;
3016
  int len = 0;
3017
3018
  if (self->Buffer.all.NameInformation.FileNameLength > 0) {
3019
    len = (self->Length - self->Buffer.all.NameInformation.FileNameLength);
3020
  }
3021
3022
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
3023
  out_uint32_le(s, self->Length);
3024
  if (self->Length > 0) {
3025
    //out_uint8a(s, self->Buffer.bytes, ((self->Length > sizeof(union _DrDriveQueryInformationRsp_Buffer)) ? sizeof(union _DrDriveQueryInformationRsp_Buffer) : self->Length));
3026
    out_uint8a(s, self->Buffer.bytes, (len > sizeof(union _DrDriveQueryInformationRsp_Buffer)) ? sizeof(union _DrDriveQueryInformationRsp_Buffer) : len);
3027
  }
3028
  if (self->Buffer.all.NameInformation.FileNameLength > 0) {
3029
    out_uint8a(s, self->Buffer.all.NameInformation.FileName, self->Buffer.all.NameInformation.FileNameLength);
3030
  }
3031
  else {
3032
    out_uint8(s, 0x00);
3033
  }
3034
3035
  return rv;
3036
}
3037
3038
3039
3040
/***/
3041
int APP_CC
3042
send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP * self, struct stream * s) {
3043
  int rv = 0;
3044
3045
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
3046
  out_uint32_le(s, self->Length);
3047
  if (self->Length > 0) {
3048
    out_uint8a(s, self->Buffer, self->Length);
3049
  }
3050
  //out_uint8(s, self->Padding);
3051
3052
  return rv;
3053
}
3054
3055
3056
3057
/***/
3058
int APP_CC
3059
send_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP * self, struct stream * s) {
3060
  int rv = 0;
3061
3062
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
3063
  out_uint8a(s, self->Padding, 5);
3064
3065
  return rv;
3066
}
3067
3068
3069
/***/
3070
int APP_CC
3071
send_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP * self, struct stream * s) {
3072
  int rv = 0;
3073
3074
  send_RDPDR_HEADER(&(self->Header), s);
3075
  out_uint16_le(s, self->VersionMajor);
3076
  out_uint16_le(s, self->VersionMinor);
3077
  out_uint32_le(s, self->ClientId);
3078
3079
  return rv;
3080
}
3081
3082
3083
3084
/***/
3085
int APP_CC
3086
send_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ * self, struct stream * s) {
3087
  int rv = 0;
3088
3089
  send_RDPDR_HEADER(&(self->Header), s);
3090
  out_uint32_le(s, self->UnicodeFlag);
3091
  out_uint32_le(s, self->CodePage);
3092
  out_uint32_le(s, self->ComputerNameLen);
3093
  if (self->ComputerNameLen > 0) {
3094
    out_uint8a(s, self->ComputerName, self->ComputerNameLen);
3095
  }
3096
3097
  return rv;
3098
}
3099
3100
int APP_CC get_DR_DRIVE_SET_INFORMATION_RSP(DR_DRIVE_SET_INFORMATION_RSP * self, struct stream * s) {
3101
  int rv = 0;
3102
3103
  get_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
3104
  in_uint32_le(s, self->Length);
3105
  //in_uint8(s, self->Padding);
3106
3107
  return rv;
3108
}
3109
3110
int APP_CC send_DR_DRIVE_SET_INFORMATION_RSP(DR_DRIVE_SET_INFORMATION_RSP * self, struct stream * s) {
3111
  int rv = 0;
3112
3113
  send_DR_DEVICE_IOCOMPLETION(&(self->DeviceIoReply), s);
3114
  out_uint32_le(s, self->Length);
3115
  out_uint8(s, self->Padding);
3116
3117
  return rv;
3118
}
3119
3120
int APP_CC get_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 * self, struct stream * s) {
3121
  int rv = 0;
3122
  return rv;
3123
}
3124
3125
int APP_CC get_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 * self, struct stream * s) {
3126
  int rv = 0;
3127
  return rv;
3128
}
3129
3130
int APP_CC get_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP * self, struct stream * s) {
3131
  int rv = 0;
3132
  BYTE hdr = 0x00;
3133
3134
  in_uint8(s, hdr);
3135
  in_uint8(s, self->Pad);
3136
  in_uint16_le(s, self->Version);
3137
3138
  self->Cmd = (hdr & 0xf0) >> 4;
3139
  self->Sp = (hdr & 0x0C) >> 2;
3140
  self->cbChId = (hdr & 0x03);
3141
3142
  return rv;
3143
}
3144
3145
int APP_CC get_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ * self, struct stream * s) {
3146
  int rv = 0;
3147
  int idx = 0;
3148
  BYTE ch = 0;
3149
  BYTE cid1 = 0;
3150
  WORD cid2 = 0;
3151
  DWORD cid4 = 0;
3152
  BYTE hdr = 0x00;
3153
3154
  in_uint8(s, hdr);
3155
3156
  self->Cmd = (hdr & 0xf0) >> 4;
3157
  self->Pri = (hdr & 0x0C) >> 2;
3158
  self->cbChId = (hdr & 0x03);
3159
3160
  self->ChannelId = 0;
3161
  if (self->cbChId == DRDYNVC_BYTE) {
3162
    in_uint8(s, cid1);
3163
    self->ChannelId += cid1;
3164
  }
3165
  if (self->cbChId == DRDYNVC_WORD) {
3166
    in_uint16_le(s, cid2);
3167
    self->ChannelId += cid2;
3168
  }
3169
  if (self->cbChId > DRDYNVC_WORD) {
3170
    in_uint32_le(s, cid4);
3171
    self->ChannelId += cid4;
3172
  }
3173
  do {
3174
    in_uint8(s, ch);
3175
    self->ChannelName[idx] = ch;
3176
    idx++;
3177
  } while (ch != '\0' && idx < 48);
3178
3179
  return rv;
3180
}
3181
3182
int APP_CC get_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP * self, struct stream * s) {
3183
    int rv = 0;
3184
    BYTE hdr = 0x00;
3185
    union {
3186
      BYTE			hdr;
3187
      DYNVC_CREATE_RSP		rsp;
3188
    } tmp;
3189
3190
    if (self == NULL || s == NULL) {
3191
      rv = -1;
3192
      goto end;
3193
    }
3194
3195
    in_uint8(s, hdr);
3196
3197
    tmp.rsp.Cmd = (hdr & 0xf0) >> 4;
3198
    tmp.rsp.Sp = (hdr & 0x0f) >> 2;
3199
    tmp.rsp.cbChId = (hdr & 0x03);
3200
3201
    self->Cmd = tmp.rsp.Cmd;
3202
    self->Sp = tmp.rsp.Sp;
3203
    self->cbChId = tmp.rsp.cbChId;
3204
3205
    if (tmp.rsp.Cmd != DRDYNVC_CREATE) {
3206
      rv = -1;
3207
      goto end;
3208
    }
3209
    tmp.rsp.ChannelId = 0;
3210
    if (tmp.rsp.cbChId == DRDYNVC_BYTE) {
3211
      BYTE cid1 = 0;
3212
      in_uint8(s, cid1);
3213
      tmp.rsp.ChannelId += cid1;
3214
    }
3215
    else if (tmp.rsp.cbChId == DRDYNVC_WORD) {
3216
      WORD cid2 = 0;
3217
      in_uint16_le(s, cid2);
3218
      tmp.rsp.ChannelId += cid2;
3219
    }
3220
    else if (tmp.rsp.cbChId > DRDYNVC_WORD) {
3221
      DWORD cid4 = 0;
3222
      in_uint32_le(s, cid4);
3223
      tmp.rsp.ChannelId += cid4;
3224
    }
3225
    in_sint32_le(s, tmp.rsp.CreationStatus);
3226
3227
    self->ChannelId = tmp.rsp.ChannelId;
3228
    self->CreationStatus = tmp.rsp.CreationStatus;
3229
3230
  end:;
3231
    return rv;
3232
}
3233
3234
int APP_CC get_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST * self, struct stream * s) {
3235
    int rv = 0;
3236
    BYTE hdr = 0x00;
3237
    union {
3238
      BYTE			hdr;
3239
      DYNVC_DATA_FIRST		rsp;
3240
    } tmp;
3241
3242
    if (self == NULL || s == NULL) {
3243
      rv = -1;
3244
      goto end;
3245
    }
3246
3247
    in_uint8(s, hdr);
3248
3249
    self->Cmd = (hdr & 0xf0) >> 4;
3250
    self->Len = (hdr & 0x0C) >> 2;
3251
    self->cbChId = (hdr & 0x03);
3252
    tmp.rsp.Cmd = self->Cmd;
3253
    tmp.rsp.Len = self->Len;
3254
    tmp.rsp.cbChId = self->cbChId;
3255
3256
    if (tmp.rsp.Cmd != DRDYNVC_DATAFIRST) {
3257
      rv = -1;
3258
      goto end;
3259
    }
3260
    tmp.rsp.ChannelId = 0;
3261
    if (tmp.rsp.cbChId == DRDYNVC_BYTE) {
3262
      BYTE cid1 = 0;
3263
      in_uint8(s, cid1);
3264
      tmp.rsp.ChannelId += cid1;
3265
    }
3266
    else if (tmp.rsp.cbChId == DRDYNVC_WORD) {
3267
      WORD cid2 = 0;
3268
      in_uint16_le(s, cid2);
3269
      tmp.rsp.ChannelId += cid2;
3270
    }
3271
    else if (tmp.rsp.cbChId > DRDYNVC_WORD) {
3272
      DWORD cid4 = 0;
3273
      in_uint32_le(s, cid4);
3274
      tmp.rsp.ChannelId += cid4;
3275
    }
3276
    tmp.rsp.Length = 0;
3277
    if (tmp.rsp.Len == DRDYNVC_BYTE) {
3278
      BYTE len1 = 0;
3279
      in_uint8(s, len1);
3280
      tmp.rsp.Length += len1;
3281
    }
3282
    else if (tmp.rsp.Len == DRDYNVC_WORD) {
3283
      WORD len2 = 0;
3284
      in_uint16_le(s, len2);
3285
      tmp.rsp.Length += len2;
3286
    }
3287
    else if (tmp.rsp.Len > DRDYNVC_WORD) {
3288
      DWORD len4 = 0;
3289
      in_uint32_le(s, len4);
3290
      tmp.rsp.Length += len4;
3291
    }
3292
3293
    self->Cmd = tmp.rsp.Cmd;
3294
    self->Len = tmp.rsp.Len;
3295
    self->cbChId = tmp.rsp.cbChId;
3296
    self->ChannelId = tmp.rsp.ChannelId;
3297
    self->Length = tmp.rsp.Length;
3298
3299
    if (tmp.rsp.Length > 0) {
3300
      in_uint8a(s, self->Data, tmp.rsp.Length);
3301
    }
3302
3303
  end:;
3304
    return rv;
3305
}
3306
3307
int APP_CC get_DYNVC_DATA(DYNVC_DATA * self, struct stream * s) {
3308
    int rv = 0;
3309
    BYTE hdr = 0x00;
3310
    union {
3311
      BYTE			hdr;
3312
      DYNVC_DATA		rsp;
3313
    } tmp;
3314
3315
    if (self == NULL || s == NULL) {
3316
      rv = -1;
3317
      goto end;
3318
    }
3319
3320
    in_uint8(s, hdr);
3321
3322
    self->Cmd = (hdr & 0xf0) >> 4;
3323
    self->Sp = (hdr & 0x0C) >> 2;
3324
    self->cbChId = (hdr & 0x03);
3325
    tmp.rsp.Cmd = self->Cmd;
3326
    tmp.rsp.Sp = self->Sp;
3327
    tmp.rsp.cbChId = self->cbChId;
3328
3329
    if (tmp.rsp.Cmd != DRDYNVC_DATA) {
3330
      rv = -1;
3331
      goto end;
3332
    }
3333
    tmp.rsp.ChannelId = 0;
3334
    if (tmp.rsp.cbChId == DRDYNVC_BYTE) {
3335
      BYTE cid1 = 0;
3336
      in_uint8(s, cid1);
3337
      tmp.rsp.ChannelId += cid1;
3338
    }
3339
    else if (tmp.rsp.cbChId == DRDYNVC_WORD) {
3340
      WORD cid2 = 0;
3341
      in_uint16_le(s, cid2);
3342
      tmp.rsp.ChannelId += cid2;
3343
    }
3344
    else if (tmp.rsp.cbChId > DRDYNVC_WORD) {
3345
      DWORD cid4 = 0;
3346
      in_uint32_le(s, cid4);
3347
      tmp.rsp.ChannelId += cid4;
3348
    }
3349
    if (s->data != NULL && s->p != NULL && s->end > s->p) {
3350
      self->Length = (s->end - s->p);
3351
      in_uint8a(s, self->Data, self->Length);
3352
    }
3353
3354
    self->Cmd = tmp.rsp.Cmd;
3355
    self->Sp = tmp.rsp.Sp;
3356
    self->cbChId = tmp.rsp.cbChId;
3357
    self->ChannelId = tmp.rsp.ChannelId;
3358
3359
  end:;
3360
    return rv;
3361
}
3362
3363
int APP_CC get_DYNVC_CLOSE(DYNVC_CLOSE * self, struct stream * s) {
3364
    int rv = 0;
3365
    BYTE hdr = 0x00;
3366
    union {
3367
      BYTE			hdr;
3368
      DYNVC_CLOSE		rsp;
3369
    } tmp;
3370
3371
    if (self == NULL || s == NULL) {
3372
      rv = -1;
3373
      goto end;
3374
    }
3375
3376
    in_uint8(s, hdr);
3377
3378
    self->Cmd = (hdr & 0xf0) >> 4;
3379
    self->Sp = (hdr & 0x0C) >> 2;
3380
    self->cbChId = (hdr & 0x03);
3381
    tmp.rsp.Cmd = self->Cmd;
3382
    tmp.rsp.Sp = self->Sp;
3383
    tmp.rsp.cbChId = self->cbChId;
3384
3385
    if (tmp.rsp.Cmd != DRDYNVC_CLOSE) {
3386
      rv = -1;
3387
      goto end;
3388
    }
3389
    tmp.rsp.ChannelId = 0;
3390
    if (tmp.rsp.cbChId == DRDYNVC_BYTE) {
3391
      BYTE cid1 = 0;
3392
      in_uint8(s, cid1);
3393
      tmp.rsp.ChannelId += cid1;
3394
    }
3395
    else if (tmp.rsp.cbChId == DRDYNVC_WORD) {
3396
      WORD cid2 = 0;
3397
      in_uint16_le(s, cid2);
3398
      tmp.rsp.ChannelId += cid2;
3399
    }
3400
    else if (tmp.rsp.cbChId > DRDYNVC_WORD) {
3401
      DWORD cid4 = 0;
3402
      in_uint32_le(s, cid4);
3403
      tmp.rsp.ChannelId += cid4;
3404
    }
3405
3406
    self->Cmd = tmp.rsp.Cmd;
3407
    self->Sp = tmp.rsp.Sp;
3408
    self->cbChId = tmp.rsp.cbChId;
3409
    self->ChannelId = tmp.rsp.ChannelId;
3410
3411
  end:;
3412
    return rv;
3413
}
3414
3415
3416
/****/
3417
3418
int APP_CC send_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 * self, struct stream * s) {
3419
    int rv = 0;
3420
    BYTE hdr = 0x00;
3421
3422
    if (self == NULL || s == NULL) {
3423
      rv = -1;
3424
      goto end;
3425
    }
3426
3427
    //hdr = (BYTE *)self;
3428
    hdr = (self->cbChId) | ((self->Sp << 2) | (self->Cmd << 4));
3429
3430
    out_uint8(s, hdr);
3431
    out_uint8(s, self->Pad);
3432
    out_uint16_le(s, self->Version);
3433
    out_uint16_le(s, self->PriorityCharge0);
3434
    out_uint16_le(s, self->PriorityCharge1);
3435
    out_uint16_le(s, self->PriorityCharge2);
3436
    out_uint16_le(s, self->PriorityCharge3);
3437
3438
  end:;
3439
    return rv;
3440
}
3441
3442
int APP_CC send_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 * self, struct stream * s) {
3443
    int rv = 0;
3444
    BYTE hdr = 0x00;
3445
3446
    if (self == NULL || s == NULL) {
3447
      rv = -1;
3448
      goto end;
3449
    }
3450
3451
    //hdr = (BYTE *)self;
3452
    hdr = (self->cbChId) | ((self->Sp << 2) | (self->Cmd << 4));
3453
3454
    out_uint8(s, hdr);
3455
    out_uint8(s, self->Pad);
3456
    out_uint16_le(s, self->Version);
3457
3458
  end:;
3459
    return rv;
3460
}
3461
3462
int APP_CC send_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP * self, struct stream * s) {
3463
    int rv = 0;
3464
    BYTE hdr = 0x00;
3465
3466
    if (self == NULL || s == NULL) {
3467
      rv = -1;
3468
      goto end;
3469
    }
3470
3471
    //hdr = (BYTE *)self;
3472
    hdr = (self->cbChId) | ((self->Sp << 2) | (self->Cmd << 4));
3473
3474
    out_uint8(s, hdr);
3475
    out_uint8(s, self->Pad);
3476
    out_uint16_le(s, (WORD)(self->Version));
3477
3478
  end:;
3479
    return rv;
3480
}
3481
3482
int APP_CC send_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ * self, struct stream * s) {
3483
    int rv = 0;
3484
    int len = 0;
3485
    BYTE hdr = 0x00;
3486
    BYTE id1 = 0x00;
3487
    WORD id2 = 0x0000;
3488
    DWORD id4 = 0x00000000;
3489
    uint8_t cbChId = 0x00;
3490
    uint8_t Pri = 0x00;
3491
    uint8_t Cmd = 0x00;
3492
3493
    if (self == NULL || s == NULL) {
3494
      rv = -1;
3495
      goto end;
3496
    }
3497
3498
    //hdr = (BYTE *)self;
3499
    //hdr = (self->cbChId & 0x00000003) | (((self->Pri & 0x0000000f) << 2) | ((self->Cmd & 0x000000f0) << 4));
3500
    cbChId = (self->cbChId & 0x00000003);
3501
    Pri = (self->Pri & 0x00000003) << 2;
3502
    Cmd = (self->Cmd & 0x000000f) << 4;
3503
    hdr = Cmd | Pri | cbChId;
3504
3505
    out_uint8(s, hdr);
3506
3507
    switch (self->cbChId) {
3508
      case DRDYNVC_BYTE:	/*	ChannelId is one byte in length		*/
3509
	id1 += self->ChannelId;
3510
	out_uint8(s, id1);
3511
	break;
3512
      case DRDYNVC_WORD:	/*	ChannelId is two bytes in length	*/
3513
	id2 += self->ChannelId;
3514
	out_uint16_le(s, id2);
3515
	break;
3516
      case DRDYNVC_DWORD:	/*	ChannelId is four bytes in length	*/
3517
      case DRDYNVC_DWORD_ALT:
3518
	id4 += self->ChannelId;
3519
	out_uint32_le(s, id4);
3520
	break;
3521
    }
3522
3523
    len = g_strnlen((char *)(self->ChannelName), 47);
3524
    if (len > 0) {
3525
      out_uint8a(s, self->ChannelName, len);
3526
      out_uint8(s, '\0');
3527
    }
3528
3529
  end:;
3530
    return rv;
3531
}
3532
3533
int APP_CC send_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP * self, struct stream * s) {
3534
    int rv = 0;
3535
    BYTE hdr = 0x00;
3536
    BYTE id1 = 0x00;
3537
    WORD id2 = 0x0000;
3538
    DWORD id4 = 0x00000000;
3539
3540
    if (self == NULL || s == NULL) {
3541
      rv = -1;
3542
      goto end;
3543
    }
3544
3545
    //hdr = (BYTE *)self;
3546
    hdr = (self->cbChId) | ((self->Sp << 2) | (self->Cmd << 4));
3547
    out_uint8(s, hdr);
3548
3549
    switch (self->cbChId) {
3550
      case DRDYNVC_BYTE:	/*	ChannelId is one byte in length		*/
3551
	id1 += self->ChannelId;
3552
	out_uint8(s, id1);
3553
	break;
3554
      case DRDYNVC_WORD:	/*	ChannelId is two bytes in length	*/
3555
	id2 += self->ChannelId;
3556
	out_uint16_le(s, id2);
3557
	break;
3558
      case DRDYNVC_DWORD:	/*	ChannelId is four bytes in length	*/
3559
      case DRDYNVC_DWORD_ALT:
3560
      default:
3561
	id4 += self->ChannelId;
3562
	out_uint32_le(s, id4);
3563
	break;
3564
    }
3565
3566
    out_uint32_le(s, self->CreationStatus);
3567
3568
  end:;
3569
    return rv;
3570
}
3571
3572
int APP_CC send_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST * self, struct stream * s) {
3573
    int rv = 0;
3574
    BYTE hdr = 0;
3575
    BYTE id1 = 0x00;
3576
    WORD id2 = 0x0000;
3577
    DWORD id4 = 0x00000000;
3578
    uint8_t cbChId = 0x00;
3579
    uint8_t Len = 0x00;
3580
    uint8_t Cmd = 0x00;
3581
    size_t l1 = 0;
3582
    size_t l2 = 0;
3583
3584
    if (self == NULL || s == NULL) {
3585
      rv = -1;
3586
      goto end;
3587
    }
3588
3589
    //hdr = (BYTE *)self;
3590
    //hdr = (self->cbChId) | ((self->Len << 2) | (self->Cmd << 4));
3591
    cbChId = (self->cbChId & 0x00000003);
3592
    Len = (self->Len & 0x00000003) << 2;
3593
    Cmd = (self->Cmd & 0x000000f) << 4;
3594
    hdr = Cmd | Len | cbChId;
3595
3596
    out_uint8(s, hdr);
3597
3598
    switch (self->cbChId) {
3599
      case DRDYNVC_BYTE:	/*	ChannelId is one byte in length		*/
3600
	l1 = 1;
3601
	id1 = (self->ChannelId & 0x000000ff);
3602
	out_uint8(s, id1);
3603
	break;
3604
      case DRDYNVC_WORD:	/*	ChannelId is two bytes in length	*/
3605
	l1 = 2;
3606
	id2 = (self->ChannelId & 0x0000ffff);
3607
	out_uint16_le(s, id2);
3608
	break;
3609
      case DRDYNVC_DWORD:	/*	ChannelId is four bytes in length	*/
3610
      case DRDYNVC_DWORD_ALT:
3611
	l1 = 4;
3612
	id4 = self->ChannelId;
3613
	out_uint32_le(s, id4);
3614
	break;
3615
    }
3616
3617
    id1 = 0;
3618
    id2 = 0;
3619
    id4 = 0;
3620
    switch (self->Len) {
3621
      case DRDYNVC_BYTE:	/*	Length is one byte in length		*/
3622
	l2 = 1;
3623
	id1 = (self->Length & 0x000000ff);
3624
	out_uint8(s, id1);
3625
	break;
3626
      case DRDYNVC_WORD:	/*	Length is two bytes in length	*/
3627
	l2 = 2;
3628
	id2 = (self->Length & 0x0000ffff);
3629
	out_uint16_le(s, id2);
3630
	break;
3631
      case DRDYNVC_DWORD:	/*	Length is four bytes in length	*/
3632
      case DRDYNVC_DWORD_ALT:
3633
	l2 = 4;
3634
	id4 = self->Length;
3635
	out_uint32_le(s, id4);
3636
	break;
3637
    }
3638
3639
    if (self->Length > 0) {
3640
	out_uint8a(s, self->Data, MIN((self->Length), (DRDYNVC_MAX_PDU - (1 + l1 + l2))));
3641
    }
3642
3643
  end:;
3644
    return rv;
3645
}
3646
3647
int APP_CC send_DYNVC_DATA(DYNVC_DATA * self, struct stream * s) {
3648
    int rv = 0;
3649
    BYTE hdr = 0x00;
3650
    BYTE id1 = 0x00;
3651
    WORD id2 = 0x0000;
3652
    DWORD id4 = 0x00000000;
3653
    uint8_t cbChId = 0x00;
3654
    uint8_t Sp = 0x00;
3655
    uint8_t Cmd = 0x00;
3656
    size_t l1 = 0;
3657
3658
    if (self == NULL || s == NULL) {
3659
      rv = -1;
3660
      goto end;
3661
    }
3662
3663
    //hdr = (BYTE *)self;
3664
    //hdr = (self->cbChId) | ((self->Sp << 2) | (self->Cmd << 4));
3665
    cbChId = (self->cbChId & 0x00000003);
3666
    Sp = (self->Sp & 0x00000003) << 2;
3667
    Cmd = (self->Cmd & 0x000000f) << 4;
3668
    hdr = Cmd | Sp | cbChId;
3669
3670
    out_uint8(s, hdr);
3671
3672
    switch (self->cbChId) {
3673
      case DRDYNVC_BYTE:	/*	ChannelId is one byte in length		*/
3674
	l1 = 1;
3675
	id1 = (self->ChannelId & 0x000000ff);
3676
	out_uint8(s, id1);
3677
	break;
3678
      case DRDYNVC_WORD:	/*	ChannelId is two bytes in length	*/
3679
	l1 = 2;
3680
	id2 = (self->ChannelId & 0x0000ffff);
3681
	out_uint16_le(s, id2);
3682
	break;
3683
      case DRDYNVC_DWORD:	/*	ChannelId is four bytes in length	*/
3684
      case DRDYNVC_DWORD_ALT:
3685
	l1 = 4;
3686
	id4 = self->ChannelId;
3687
	out_uint32_le(s, id4);
3688
	break;
3689
    }
3690
3691
    if (self->Length > 0) {
3692
	out_uint8a(s, self->Data, MIN(self->Length, (DRDYNVC_MAX_PDU - (1 + l1))));
3693
    }
3694
3695
  end:;
3696
    return rv;
3697
}
3698
3699
int APP_CC send_DYNVC_CLOSE(DYNVC_CLOSE * self, struct stream * s) {
3700
    int rv = 0;
3701
    BYTE hdr = 0;
3702
    BYTE id1 = 0x00;
3703
    WORD id2 = 0x0000;
3704
    DWORD id4 = 0x00000000;
3705
    uint8_t cbChId = 0x00;
3706
    uint8_t Sp = 0x00;
3707
    uint8_t Cmd = 0x00;
3708
3709
    if (self == NULL || s == NULL) {
3710
      rv = -1;
3711
      goto end;
3712
    }
3713
3714
    //hdr = (BYTE *)self;
3715
    //hdr = (self->cbChId) | ((self->Sp << 2) | (self->Cmd << 4));
3716
    cbChId = (self->cbChId & 0x00000003);
3717
    Sp = (self->Sp & 0x00000003) << 2;
3718
    Cmd = (self->Cmd & 0x000000f) << 4;
3719
    hdr = Cmd | Sp | cbChId;
3720
3721
    out_uint8(s, hdr);
3722
3723
    switch (self->cbChId) {
3724
      case DRDYNVC_BYTE:	/*	ChannelId is one byte in length		*/
3725
	id1 = (self->ChannelId & 0x000000ff);
3726
	out_uint8(s, id1);
3727
	break;
3728
      case DRDYNVC_WORD:	/*	ChannelId is two bytes in length	*/
3729
	id2 = (self->ChannelId & 0x0000ffff);
3730
	out_uint16_le(s, id2);
3731
	break;
3732
      case DRDYNVC_DWORD:	/*	ChannelId is four bytes in length	*/
3733
      case DRDYNVC_DWORD_ALT:
3734
	id4 = self->ChannelId;
3735
	out_uint32_le(s, id4);
3736
	break;
3737
    }
3738
3739
  end:;
3740
    return rv;
3741
}
3742
3743
3744
3745
/*
3746
int APP_CC
3747
send_( * self, struct stream * s) {
3748
  int rv = 0;
3749
3750
  return rv;
3751
}
3752
3753
int APP_CC
3754
get_( * self, struct stream * s) {
3755
  int rv = 0;
3756
3757
  return rv;
3758
}
3759
*/
3760
3761
/**********************************************************************
3762
 *		END:	SENDERS / GETTERS
3763
 **********************************************************************/
3764
3765
/**********************************************************************
3766
 *		BEGIN:	DESTRUCTORS
3767
 **********************************************************************/
3768
3769
void APP_CC destroy_RDPDR_HEADER(RDPDR_HEADER * self) {
3770
}
3771
3772
void APP_CC destroy_CAPABILITY_HEADER(CAPABILITY_HEADER * self) {
3773
}
3774
3775
void APP_CC destroy_CAPABILITY_SET(CAPABILITY_SET * self) {
3776
}
3777
3778
void APP_CC destroy_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE * self) {
3779
}
3780
3781
void APP_CC destroy_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST * self) {
3782
}
3783
3784
void APP_CC destroy_DR_CREATE_REQ(DR_CREATE_REQ * self) {
3785
}
3786
3787
void APP_CC destroy_DR_CLOSE_REQ(DR_CLOSE_REQ * self) {
3788
}
3789
3790
void APP_CC destroy_DR_READ_REQ(DR_READ_REQ * self) {
3791
}
3792
3793
void APP_CC destroy_DR_WRITE_REQ(DR_WRITE_REQ * self) {
3794
}
3795
3796
void APP_CC destroy_DR_CONTROL_REQ(DR_CONTROL_REQ * self) {
3797
}
3798
3799
void APP_CC destroy_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION * self) {
3800
}
3801
3802
void APP_CC destroy_DR_CREATE_RSP(DR_CREATE_RSP * self) {
3803
}
3804
3805
void APP_CC destroy_DR_CLOSE_RSP(DR_CLOSE_RSP * self) {
3806
}
3807
3808
void APP_CC destroy_DR_READ_RSP(DR_READ_RSP * self) {
3809
}
3810
3811
void APP_CC destroy_DR_WRITE_RSP(DR_WRITE_RSP * self) {
3812
}
3813
3814
void APP_CC destroy_DR_CONTROL_RSP(DR_CONTROL_RSP * self) {
3815
}
3816
3817
void APP_CC destroy_RDP_LOCK_INFO(RDP_LOCK_INFO * self) {
3818
}
3819
3820
void APP_CC destroy_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP * self) {
3821
}
3822
3823
void APP_CC destroy_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ * self) {
3824
}
3825
3826
void APP_CC destroy_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP * self) {
3827
}
3828
3829
void APP_CC destroy_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ * self) {
3830
}
3831
3832
void APP_CC destroy_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM * self) {
3833
}
3834
3835
void APP_CC destroy_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ * self) {
3836
}
3837
3838
void APP_CC destroy_GENERAL_CAPS_SET(GENERAL_CAPS_SET * self) {
3839
}
3840
3841
void APP_CC destroy_PRINTER_CAPS_SET(PRINTER_CAPS_SET * self) {
3842
}
3843
3844
void APP_CC destroy_PORT_CAPS_SET(PORT_CAPS_SET * self) {
3845
}
3846
3847
void APP_CC destroy_DRIVE_CAPS_SET(DRIVE_CAPS_SET * self) {
3848
}
3849
3850
void APP_CC destroy_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET * self) {
3851
}
3852
3853
void APP_CC destroy_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ * self) {
3854
}
3855
3856
void APP_CC destroy_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE * self) {
3857
}
3858
3859
void APP_CC destroy_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE * self) {
3860
}
3861
3862
void APP_CC destroy_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST * self) {
3863
}
3864
3865
void APP_CC destroy_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ * self) {
3866
}
3867
3868
void APP_CC destroy_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ * self) {
3869
}
3870
3871
void APP_CC destroy_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ * self) {
3872
}
3873
3874
void APP_CC destroy_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ * self) {
3875
}
3876
3877
void APP_CC destroy_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ * self) {
3878
}
3879
3880
void APP_CC destroy_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ * self) {
3881
}
3882
3883
void APP_CC destroy_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ * self) {
3884
}
3885
3886
void APP_CC destroy_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ * self) {
3887
}
3888
3889
void APP_CC destroy_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ * self) {
3890
}
3891
3892
void APP_CC destroy_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION * self) {
3893
}
3894
3895
void APP_CC destroy_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ * self) {
3896
}
3897
3898
void APP_CC destroy_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ * self) {
3899
}
3900
3901
void APP_CC destroy_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ * self) {
3902
}
3903
3904
void APP_CC destroy_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION * self) {
3905
}
3906
3907
void APP_CC destroy_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP * self) {
3908
}
3909
3910
void APP_CC destroy_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP * self) {
3911
}
3912
3913
void APP_CC destroy_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP * self) {
3914
}
3915
3916
void APP_CC destroy_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP * self) {
3917
}
3918
3919
void APP_CC destroy_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP * self) {
3920
}
3921
3922
void APP_CC destroy_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP * self) {
3923
}
3924
3925
void APP_CC destroy_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP * self) {
3926
}
3927
3928
void APP_CC destroy_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP * self) {
3929
}
3930
3931
void APP_CC destroy_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON * self) {
3932
}
3933
3934
void APP_CC destroy_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 * self) {
3935
}
3936
3937
void APP_CC destroy_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 * self) {
3938
}
3939
3940
void APP_CC destroy_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP * self) {
3941
}
3942
3943
void APP_CC destroy_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ * self) {
3944
}
3945
3946
void APP_CC destroy_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP * self) {
3947
}
3948
3949
void APP_CC destroy_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST * self) {
3950
}
3951
3952
void APP_CC destroy_DYNVC_DATA(DYNVC_DATA * self) {
3953
}
3954
3955
void APP_CC destroy_DYNVC_CLOSE(DYNVC_CLOSE * self) {  
3956
}
3957
3958
3959
3960
/**********************************************************************
3961
 *		END:	DESTRUCTORS
3962
 **********************************************************************/
3963
3964
/*****************************************************************************/
3965
void * APP_CC rdpdr_inst(const char * cname) {
3966
  void *res = NULL;
3967
  if (!g_strcasecmp(cname,"RDPDR_HEADER")) {
3968
    res = (void *)g_malloc(sizeof(RDPDR_HEADER),1);
3969
    ((RDPDR_HEADER *)res)->__destructor = &destroy_RDPDR_HEADER;
3970
    ((RDPDR_HEADER *)res)->out = &send_RDPDR_HEADER;
3971
    ((RDPDR_HEADER *)res)->in = &get_RDPDR_HEADER;
3972
    construct_RDPDR_HEADER(res);
3973
  }
3974
  else if (!g_strcasecmp(cname,"CAPABILITY_HEADER")) {
3975
    res = (void *)g_malloc(sizeof(CAPABILITY_HEADER),1);
3976
    ((CAPABILITY_HEADER *)res)->__destructor = &destroy_CAPABILITY_HEADER;
3977
    ((CAPABILITY_HEADER *)res)->out = &send_CAPABILITY_HEADER;
3978
    ((CAPABILITY_HEADER *)res)->in = &get_CAPABILITY_HEADER;
3979
    construct_CAPABILITY_HEADER(res);
3980
  }
3981
  else if (!g_strcasecmp(cname,"CAPABILITY_SET")) {
3982
    res = (void *)g_malloc(sizeof(CAPABILITY_SET),1);
3983
    ((CAPABILITY_SET *)res)->__destructor = &destroy_CAPABILITY_SET;
3984
    construct_CAPABILITY_SET(res);
3985
  }
3986
  else if (!g_strcasecmp(cname,"DEVICE_ANNOUNCE")) {
3987
    res = (void *)g_malloc(sizeof(DEVICE_ANNOUNCE),1);
3988
    ((DEVICE_ANNOUNCE *)res)->__destructor = &destroy_DEVICE_ANNOUNCE;
3989
    construct_DEVICE_ANNOUNCE(res);
3990
  }
3991
  else if (!g_strcasecmp(cname,"DR_DEVICE_IOREQUEST")) {
3992
    res = (void *)g_malloc(sizeof(DR_DEVICE_IOREQUEST),1);
3993
    ((DR_DEVICE_IOREQUEST *)res)->Header.out = &send_RDPDR_HEADER;
3994
    ((DR_DEVICE_IOREQUEST *)res)->Header.in = &get_RDPDR_HEADER;
3995
    construct_RDPDR_HEADER(&(((DR_DEVICE_IOREQUEST *)res)->Header));
3996
    ((DR_DEVICE_IOREQUEST *)res)->__destructor = &destroy_DR_DEVICE_IOREQUEST;
3997
    ((DR_DEVICE_IOREQUEST *)res)->out = &send_DR_DEVICE_IOREQUEST;
3998
    ((DR_DEVICE_IOREQUEST *)res)->in = &get_DR_DEVICE_IOREQUEST;
3999
    construct_DR_DEVICE_IOREQUEST(res);
4000
  }
4001
  else if (!g_strcasecmp(cname,"DR_CREATE_REQ")) {
4002
    res = (void *)g_malloc(sizeof(DR_CREATE_REQ),1);
4003
    ((DR_CREATE_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4004
    ((DR_CREATE_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4005
    construct_RDPDR_HEADER(&(((DR_CREATE_REQ *)res)->DeviceIoRequest.Header));
4006
    ((DR_CREATE_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4007
    ((DR_CREATE_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4008
    construct_DR_DEVICE_IOREQUEST(&(((DR_CREATE_REQ *)res)->DeviceIoRequest));
4009
    ((DR_CREATE_REQ *)res)->__destructor = &destroy_DR_CREATE_REQ;
4010
    ((DR_CREATE_REQ *)res)->out = &send_DR_CREATE_REQ;
4011
    ((DR_CREATE_REQ *)res)->in = &get_DR_CREATE_REQ;
4012
    construct_DR_CREATE_REQ(res);
4013
  }
4014
  else if (!g_strcasecmp(cname,"DR_CLOSE_REQ")) {
4015
    res = (void *)g_malloc(sizeof(DR_CLOSE_REQ),1);
4016
    ((DR_CLOSE_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4017
    ((DR_CLOSE_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4018
    construct_RDPDR_HEADER(&(((DR_CLOSE_REQ *)res)->DeviceIoRequest.Header));
4019
    ((DR_CLOSE_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4020
    ((DR_CLOSE_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4021
    construct_DR_DEVICE_IOREQUEST(&(((DR_CLOSE_REQ *)res)->DeviceIoRequest));
4022
    ((DR_CLOSE_REQ *)res)->__destructor = &destroy_DR_CLOSE_REQ;
4023
    ((DR_CLOSE_REQ *)res)->out = &send_DR_CLOSE_REQ;
4024
    ((DR_CLOSE_REQ *)res)->in = &get_DR_CLOSE_REQ;
4025
    construct_DR_CLOSE_REQ(res);
4026
  }
4027
  else if (!g_strcasecmp(cname,"DR_READ_REQ")) {
4028
    res = (void *)g_malloc(sizeof(DR_READ_REQ),1);
4029
    ((DR_READ_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4030
    ((DR_READ_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4031
    construct_RDPDR_HEADER(&(((DR_READ_REQ *)res)->DeviceIoRequest.Header));
4032
    ((DR_READ_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4033
    ((DR_READ_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4034
    construct_DR_DEVICE_IOREQUEST(&(((DR_READ_REQ *)res)->DeviceIoRequest));
4035
    ((DR_READ_REQ *)res)->__destructor = &destroy_DR_READ_REQ;
4036
    ((DR_READ_REQ *)res)->out = &send_DR_READ_REQ;
4037
    ((DR_READ_REQ *)res)->in = &get_DR_READ_REQ;
4038
    construct_DR_READ_REQ(res);
4039
  }
4040
  else if (!g_strcasecmp(cname,"DR_WRITE_REQ")) {
4041
    res = (void *)g_malloc(sizeof(DR_WRITE_REQ),1);
4042
    ((DR_WRITE_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4043
    ((DR_WRITE_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4044
    construct_RDPDR_HEADER(&(((DR_WRITE_REQ *)res)->DeviceIoRequest.Header));
4045
    ((DR_WRITE_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4046
    ((DR_WRITE_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4047
    construct_DR_DEVICE_IOREQUEST(&(((DR_WRITE_REQ *)res)->DeviceIoRequest));
4048
    ((DR_WRITE_REQ *)res)->__destructor = &destroy_DR_WRITE_REQ;
4049
    ((DR_WRITE_REQ *)res)->out = &send_DR_WRITE_REQ;
4050
    ((DR_WRITE_REQ *)res)->in = &get_DR_WRITE_REQ;
4051
    construct_DR_WRITE_REQ(res);
4052
  }
4053
  else if (!g_strcasecmp(cname,"DR_CONTROL_REQ")) {
4054
    res = (void *)g_malloc(sizeof(DR_CONTROL_REQ),1);
4055
    ((DR_CONTROL_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4056
    ((DR_CONTROL_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4057
    construct_RDPDR_HEADER(&(((DR_CONTROL_REQ *)res)->DeviceIoRequest.Header));
4058
    ((DR_CONTROL_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4059
    ((DR_CONTROL_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4060
    construct_DR_DEVICE_IOREQUEST(&(((DR_CONTROL_REQ *)res)->DeviceIoRequest));
4061
    ((DR_CONTROL_REQ *)res)->__destructor = &destroy_DR_CONTROL_REQ;
4062
    ((DR_CONTROL_REQ *)res)->out = &send_DR_CONTROL_REQ;
4063
    ((DR_CONTROL_REQ *)res)->in = &get_DR_CONTROL_REQ;
4064
    construct_DR_CONTROL_REQ(res);
4065
  }
4066
  else if (!g_strcasecmp(cname,"DR_DEVICE_IOCOMPLETION")) {
4067
    res = (void *)g_malloc(sizeof(DR_DEVICE_IOCOMPLETION),1);
4068
    ((DR_DEVICE_IOCOMPLETION *)res)->Header.out = &send_RDPDR_HEADER;
4069
    ((DR_DEVICE_IOCOMPLETION *)res)->Header.in = &get_RDPDR_HEADER;
4070
    construct_RDPDR_HEADER(&(((DR_DEVICE_IOCOMPLETION *)res)->Header));
4071
    ((DR_DEVICE_IOCOMPLETION *)res)->__destructor = &destroy_DR_DEVICE_IOCOMPLETION;
4072
    ((DR_DEVICE_IOCOMPLETION *)res)->in = &get_DR_DEVICE_IOCOMPLETION;
4073
    ((DR_DEVICE_IOCOMPLETION *)res)->out = &send_DR_DEVICE_IOCOMPLETION;
4074
    construct_DR_DEVICE_IOCOMPLETION(res);
4075
  }
4076
  else if (!g_strcasecmp(cname,"DR_CREATE_RSP")) {
4077
    res = (void *)g_malloc(sizeof(DR_CREATE_RSP),1);
4078
    construct_RDPDR_HEADER(&(((DR_CREATE_RSP *)res)->DeviceIoReply.Header));
4079
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_CREATE_RSP *)res)->DeviceIoReply));
4080
    construct_DR_CREATE_RSP(res);
4081
    ((DR_CREATE_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4082
    ((DR_CREATE_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4083
    ((DR_CREATE_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4084
    ((DR_CREATE_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4085
    ((DR_CREATE_RSP *)res)->DeviceIoReply.Header.__destructor = NULL;
4086
    ((DR_CREATE_RSP *)res)->DeviceIoReply.__destructor = NULL;
4087
    ((DR_CREATE_RSP *)res)->__destructor = NULL;
4088
    ((DR_CREATE_RSP *)res)->out = &send_DR_CREATE_RSP;
4089
    ((DR_CREATE_RSP *)res)->in = &get_DR_CREATE_RSP;
4090
  }
4091
  else if (!g_strcasecmp(cname,"DR_CLOSE_RSP")) {
4092
    res = (void *)g_malloc(sizeof(DR_CLOSE_RSP),1);
4093
    construct_RDPDR_HEADER(&(((DR_CLOSE_RSP *)res)->DeviceIoReply.Header));
4094
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_CLOSE_RSP *)res)->DeviceIoReply));
4095
    construct_DR_CLOSE_RSP(res);
4096
    ((DR_CLOSE_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4097
    ((DR_CLOSE_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4098
    ((DR_CLOSE_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4099
    ((DR_CLOSE_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4100
    ((DR_CLOSE_RSP *)res)->DeviceIoReply.Header.__destructor = NULL;
4101
    ((DR_CLOSE_RSP *)res)->DeviceIoReply.__destructor = NULL;
4102
    ((DR_CLOSE_RSP *)res)->__destructor = NULL;
4103
    ((DR_CLOSE_RSP *)res)->out = &send_DR_CLOSE_RSP;
4104
    ((DR_CLOSE_RSP *)res)->in = &get_DR_CLOSE_RSP;
4105
  }
4106
  else if (!g_strcasecmp(cname,"DR_READ_RSP") || !g_strcasecmp(cname, "DR_DRIVE_READ_RSP")) {
4107
    res = (void *)g_malloc(sizeof(DR_READ_RSP),1);
4108
    ((DR_READ_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4109
    ((DR_READ_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4110
    construct_RDPDR_HEADER(&(((DR_READ_RSP *)res)->DeviceIoReply.Header));
4111
    ((DR_READ_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4112
    ((DR_READ_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4113
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_READ_RSP *)res)->DeviceIoReply));
4114
    ((DR_READ_RSP *)res)->__destructor = &destroy_DR_READ_RSP;
4115
    ((DR_READ_RSP *)res)->out = &send_DR_READ_RSP;
4116
    ((DR_READ_RSP *)res)->in = &get_DR_READ_RSP;
4117
    construct_DR_READ_RSP(res);
4118
  }
4119
  else if (!g_strcasecmp(cname,"DR_WRITE_RSP") || !g_strcasecmp(cname,"DR_DRIVE_WRITE_RSP")) {
4120
    res = (void *)g_malloc(sizeof(DR_WRITE_RSP),1);
4121
    ((DR_WRITE_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4122
    ((DR_WRITE_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4123
    construct_RDPDR_HEADER(&(((DR_WRITE_RSP *)res)->DeviceIoReply.Header));
4124
    ((DR_WRITE_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4125
    ((DR_WRITE_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4126
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_WRITE_RSP *)res)->DeviceIoReply));
4127
    ((DR_WRITE_RSP *)res)->__destructor = &destroy_DR_WRITE_RSP;
4128
    ((DR_WRITE_RSP *)res)->out = &send_DR_WRITE_RSP;
4129
    ((DR_WRITE_RSP *)res)->in = &get_DR_WRITE_RSP;
4130
    construct_DR_WRITE_RSP(res);
4131
  }
4132
  else if (!g_strcasecmp(cname,"DR_CONTROL_RSP") || !g_strcasecmp(cname,"DR_DRIVE_CONTROL_RSP")) {
4133
    res = (void *)g_malloc(sizeof(DR_CONTROL_RSP),1);
4134
    ((DR_CONTROL_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4135
    ((DR_CONTROL_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4136
    construct_RDPDR_HEADER(&(((DR_CONTROL_RSP *)res)->DeviceIoReply.Header));
4137
    ((DR_CONTROL_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4138
    ((DR_CONTROL_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4139
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_CONTROL_RSP *)res)->DeviceIoReply));
4140
    ((DR_CONTROL_RSP *)res)->__destructor = &destroy_DR_CONTROL_RSP;
4141
    ((DR_CONTROL_RSP *)res)->out = &send_DR_CONTROL_RSP;
4142
    ((DR_CONTROL_RSP *)res)->in = &get_DR_CONTROL_RSP;
4143
    construct_DR_CONTROL_RSP(res);
4144
  }
4145
  else if (!g_strcasecmp(cname,"RDP_LOCK_INFO")) {
4146
    res = (void *)g_malloc(sizeof(RDP_LOCK_INFO),1);
4147
    ((RDP_LOCK_INFO *)res)->__destructor = &destroy_RDP_LOCK_INFO;
4148
    ((RDP_LOCK_INFO *)res)->out = &send_RDP_LOCK_INFO;
4149
    ((RDP_LOCK_INFO *)res)->in = &get_RDP_LOCK_INFO;
4150
    construct_RDP_LOCK_INFO(res);
4151
  }
4152
  else if (!g_strcasecmp(cname,"DR_CORE_DEVICE_ANNOUNCE_RSP")) {
4153
    res = (void *)g_malloc(sizeof(DR_CORE_DEVICE_ANNOUNCE_RSP),1);
4154
    ((DR_CORE_DEVICE_ANNOUNCE_RSP *)res)->Header.out = &send_RDPDR_HEADER;
4155
    ((DR_CORE_DEVICE_ANNOUNCE_RSP *)res)->Header.in = &get_RDPDR_HEADER;
4156
    construct_RDPDR_HEADER(&(((DR_CORE_DEVICE_ANNOUNCE_RSP *)res)->Header));
4157
    ((DR_CORE_DEVICE_ANNOUNCE_RSP *)res)->__destructor = &destroy_DR_CORE_DEVICE_ANNOUNCE_RSP;
4158
    ((DR_CORE_DEVICE_ANNOUNCE_RSP *)res)->in = &get_DR_CORE_DEVICE_ANNOUNCE_RSP;
4159
    ((DR_CORE_DEVICE_ANNOUNCE_RSP *)res)->out = &send_DR_CORE_DEVICE_ANNOUNCE_RSP;
4160
    construct_DR_CORE_DEVICE_ANNOUNCE_RSP(res);
4161
  }
4162
  else if (!g_strcasecmp(cname,"DR_CORE_SERVER_ANNOUNCE_REQ")) {
4163
    res = (void *)g_malloc(sizeof(DR_CORE_SERVER_ANNOUNCE_REQ),1);
4164
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->Header.out = &send_RDPDR_HEADER;
4165
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->Header.in = &get_RDPDR_HEADER;
4166
    construct_RDPDR_HEADER(&(((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->Header));
4167
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->Header.Component = RDPDR_CTYP_CORE;
4168
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->Header.PacketId = PAKID_CORE_SERVER_ANNOUNCE;
4169
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->VersionMajor = 0x0001; /* [MS-RDPEFS] @ 2.2.2.2	*/
4170
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->VersionMinor = 0x000C; /* " */
4171
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->__destructor = &destroy_DR_CORE_SERVER_ANNOUNCE_REQ;
4172
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->in = &get_DR_CORE_SERVER_ANNOUNCE_REQ;
4173
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)res)->out = &send_DR_CORE_SERVER_ANNOUNCE_REQ;
4174
    construct_DR_CORE_SERVER_ANNOUNCE_REQ(res);
4175
  }
4176
  else if (!g_strcasecmp(cname,"DR_CORE_SERVER_ANNOUNCE_RSP")) {
4177
    res = (void *)g_malloc(sizeof(DR_CORE_SERVER_ANNOUNCE_RSP),1);
4178
    ((DR_CORE_SERVER_ANNOUNCE_RSP *)res)->Header.out = &send_RDPDR_HEADER;
4179
    ((DR_CORE_SERVER_ANNOUNCE_RSP *)res)->Header.in = &get_RDPDR_HEADER;
4180
    construct_RDPDR_HEADER(&(((DR_CORE_SERVER_ANNOUNCE_RSP *)res)->Header));
4181
    ((DR_CORE_SERVER_ANNOUNCE_RSP *)res)->__destructor = &destroy_DR_CORE_SERVER_ANNOUNCE_RSP;
4182
    ((DR_CORE_SERVER_ANNOUNCE_RSP *)res)->in = &get_DR_CORE_SERVER_ANNOUNCE_RSP;
4183
    ((DR_CORE_SERVER_ANNOUNCE_RSP *)res)->out = &send_DR_CORE_SERVER_ANNOUNCE_RSP;
4184
    construct_DR_CORE_SERVER_ANNOUNCE_RSP(res);
4185
  }
4186
  else if (!g_strcasecmp(cname,"DR_CORE_CLIENT_NAME_REQ")) {
4187
    res = (void *)g_malloc(sizeof(DR_CORE_CLIENT_NAME_REQ),1);
4188
    ((DR_CORE_CLIENT_NAME_REQ *)res)->Header.out = &send_RDPDR_HEADER;
4189
    ((DR_CORE_CLIENT_NAME_REQ *)res)->Header.in = &get_RDPDR_HEADER;
4190
    construct_RDPDR_HEADER(&(((DR_CORE_CLIENT_NAME_REQ *)res)->Header));
4191
    ((DR_CORE_CLIENT_NAME_REQ *)res)->__destructor = &destroy_DR_CORE_CLIENT_NAME_REQ;
4192
    ((DR_CORE_CLIENT_NAME_REQ *)res)->in = &get_DR_CORE_CLIENT_NAME_REQ;
4193
    ((DR_CORE_CLIENT_NAME_REQ *)res)->out = &send_DR_CORE_CLIENT_NAME_REQ;
4194
    construct_DR_CORE_CLIENT_NAME_REQ(res);
4195
  }
4196
  else if (!g_strcasecmp(cname,"DR_CORE_SERVER_CLIENTID_CONFIRM")) {
4197
    res = (void *)g_malloc(sizeof(DR_CORE_SERVER_CLIENTID_CONFIRM),1);
4198
    ((DR_CORE_SERVER_CLIENTID_CONFIRM *)res)->Header.out = &send_RDPDR_HEADER;
4199
    ((DR_CORE_SERVER_CLIENTID_CONFIRM *)res)->Header.in = &get_RDPDR_HEADER;
4200
    construct_RDPDR_HEADER(&(((DR_CORE_SERVER_CLIENTID_CONFIRM *)res)->Header));
4201
    ((DR_CORE_SERVER_CLIENTID_CONFIRM *)res)->__destructor = &destroy_DR_CORE_SERVER_CLIENTID_CONFIRM;
4202
    ((DR_CORE_SERVER_CLIENTID_CONFIRM *)res)->in = &get_DR_CORE_SERVER_CLIENTID_CONFIRM;
4203
    ((DR_CORE_SERVER_CLIENTID_CONFIRM *)res)->out = &send_DR_CORE_SERVER_CLIENTID_CONFIRM;
4204
    construct_DR_CORE_SERVER_CLIENTID_CONFIRM(res);
4205
  }
4206
  else if (!g_strcasecmp(cname,"DR_CORE_CAPABILITY_REQ") || !g_strcasecmp(cname,"DR_CORE_CAPABILITY_RSP")) {
4207
    res = (void *)g_malloc(sizeof(DR_CORE_CAPABILITY_REQ),1);
4208
    ((DR_CORE_CAPABILITY_REQ *)res)->Header.out = &send_RDPDR_HEADER;
4209
    ((DR_CORE_CAPABILITY_REQ *)res)->Header.in = &get_RDPDR_HEADER;
4210
    ((DR_CORE_CAPABILITY_REQ *)res)->Header.Component = RDPDR_CTYP_CORE;
4211
    ((DR_CORE_CAPABILITY_REQ *)res)->Header.PacketId = PAKID_CORE_SERVER_CAPABILITY;
4212
    construct_RDPDR_HEADER(&(((DR_CORE_CAPABILITY_REQ *)res)->Header));
4213
    ((DR_CORE_CAPABILITY_REQ *)res)->__destructor = &destroy_DR_CORE_CAPABILITY_REQ;
4214
    ((DR_CORE_CAPABILITY_REQ *)res)->in = &get_DR_CORE_CAPABILITY_REQ;
4215
    ((DR_CORE_CAPABILITY_REQ *)res)->out = &send_DR_CORE_CAPABILITY_REQ;
4216
    construct_DR_CORE_CAPABILITY_REQ(res);
4217
  }
4218
  else if (!g_strcasecmp(cname,"GENERAL_CAPS_SET")) {
4219
    res = (void *)g_malloc(sizeof(GENERAL_CAPS_SET),1);
4220
    ((GENERAL_CAPS_SET *)res)->Header.out = &send_CAPABILITY_HEADER;
4221
    ((GENERAL_CAPS_SET *)res)->Header.in = &get_CAPABILITY_HEADER;
4222
    ((GENERAL_CAPS_SET *)res)->Header.CapabilityType = GENERAL_CAPABILITY_VERSION_02;
4223
    construct_CAPABILITY_HEADER(&(((GENERAL_CAPS_SET *)res)->Header));
4224
    ((GENERAL_CAPS_SET *)res)->protocolMajorVersion = 0x0001;
4225
    ((GENERAL_CAPS_SET *)res)->protocolMinorVersion = 0x000C;
4226
    ((GENERAL_CAPS_SET *)res)->ioCode1 = RDPDR_IRP_MJ_CREATE | RDPDR_IRP_MJ_CLEANUP | RDPDR_IRP_MJ_CLOSE | RDPDR_IRP_MJ_READ | RDPDR_IRP_MJ_WRITE | RDPDR_IRP_MJ_FLUSH_BUFFERS | RDPDR_IRP_MJ_SHUTDOWN | RDPDR_IRP_MJ_DEVICE_CONTROL | RDPDR_IRP_MJ_QUERY_VOLUME_INFORMATION | RDPDR_IRP_MJ_SET_VOLUME_INFORMATION | RDPDR_IRP_MJ_QUERY_INFORMATION | RDPDR_IRP_MJ_SET_INFORMATION | RDPDR_IRP_MJ_DIRECTORY_CONTROL | RDPDR_IRP_MJ_LOCK_CONTROL;
4227
    ((GENERAL_CAPS_SET *)res)->extendedPDU = RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU;
4228
    ((GENERAL_CAPS_SET *)res)->extraFlags1 = ENABLE_ASYNCIO;
4229
    ((GENERAL_CAPS_SET *)res)->__destructor = &destroy_GENERAL_CAPS_SET;
4230
    ((GENERAL_CAPS_SET *)res)->in = &get_GENERAL_CAPS_SET;
4231
    ((GENERAL_CAPS_SET *)res)->out = &send_GENERAL_CAPS_SET;
4232
    construct_GENERAL_CAPS_SET(res);
4233
  }
4234
  else if (!g_strcasecmp(cname,"PRINTER_CAPS_SET")) {
4235
    res = (void *)g_malloc(sizeof(PRINTER_CAPS_SET),1);
4236
    ((PRINTER_CAPS_SET *)res)->Header.out = &send_CAPABILITY_HEADER;
4237
    ((PRINTER_CAPS_SET *)res)->Header.in = &get_CAPABILITY_HEADER;
4238
    construct_CAPABILITY_HEADER(&(((PRINTER_CAPS_SET *)res)->Header));
4239
    ((PRINTER_CAPS_SET *)res)->__destructor = &destroy_PRINTER_CAPS_SET;
4240
    ((PRINTER_CAPS_SET *)res)->in = &get_PRINTER_CAPS_SET;
4241
    ((PRINTER_CAPS_SET *)res)->out = &send_PRINTER_CAPS_SET;
4242
    construct_PRINTER_CAPS_SET(res);
4243
  }
4244
  else if (!g_strcasecmp(cname,"PORT_CAPS_SET")) {
4245
    res = (void *)g_malloc(sizeof(PORT_CAPS_SET),1);
4246
    ((PORT_CAPS_SET *)res)->Header.out = &send_CAPABILITY_HEADER;
4247
    ((PORT_CAPS_SET *)res)->Header.in = &get_CAPABILITY_HEADER;
4248
    construct_CAPABILITY_HEADER(&(((PORT_CAPS_SET *)res)->Header));
4249
    ((PORT_CAPS_SET *)res)->__destructor = &destroy_PORT_CAPS_SET;
4250
    ((PORT_CAPS_SET *)res)->in = &get_PORT_CAPS_SET;
4251
    ((PORT_CAPS_SET *)res)->out = &send_PORT_CAPS_SET;
4252
    construct_PORT_CAPS_SET(res);
4253
  }
4254
  else if (!g_strcasecmp(cname,"DRIVE_CAPS_SET")) {
4255
    res = (void *)g_malloc(sizeof(DRIVE_CAPS_SET),1);
4256
    ((DRIVE_CAPS_SET *)res)->Header.out = &send_CAPABILITY_HEADER;
4257
    ((DRIVE_CAPS_SET *)res)->Header.in = &get_CAPABILITY_HEADER;
4258
    construct_CAPABILITY_HEADER(&(((DRIVE_CAPS_SET *)res)->Header));
4259
    ((DRIVE_CAPS_SET *)res)->__destructor = &destroy_DRIVE_CAPS_SET;
4260
    ((DRIVE_CAPS_SET *)res)->in = &get_DRIVE_CAPS_SET;
4261
    ((DRIVE_CAPS_SET *)res)->out = &send_DRIVE_CAPS_SET;
4262
    construct_DRIVE_CAPS_SET(res);
4263
  }
4264
  else if (!g_strcasecmp(cname,"SMARTCARD_CAPS_SET")) {
4265
    res = (void *)g_malloc(sizeof(SMARTCARD_CAPS_SET),1);
4266
    ((SMARTCARD_CAPS_SET *)res)->Header.out = &send_CAPABILITY_HEADER;
4267
    ((SMARTCARD_CAPS_SET *)res)->Header.in = &get_CAPABILITY_HEADER;
4268
    construct_CAPABILITY_HEADER(&(((SMARTCARD_CAPS_SET *)res)->Header));
4269
    ((SMARTCARD_CAPS_SET *)res)->__destructor = &destroy_SMARTCARD_CAPS_SET;
4270
    ((SMARTCARD_CAPS_SET *)res)->in = &get_SMARTCARD_CAPS_SET;
4271
    ((SMARTCARD_CAPS_SET *)res)->out = &send_SMARTCARD_CAPS_SET;
4272
    construct_SMARTCARD_CAPS_SET(res);
4273
  }
4274
  else if (!g_strcasecmp(cname,"DR_CORE_DEVICELIST_ANNOUNCE_REQ")) {
4275
    res = (void *)g_malloc(sizeof(DR_CORE_DEVICELIST_ANNOUNCE_REQ),1);
4276
    ((DR_CORE_DEVICELIST_ANNOUNCE_REQ *)res)->Header.out = &send_RDPDR_HEADER;
4277
    ((DR_CORE_DEVICELIST_ANNOUNCE_REQ *)res)->Header.in = &get_RDPDR_HEADER;
4278
    construct_RDPDR_HEADER(&(((DR_CORE_DEVICELIST_ANNOUNCE_REQ *)res)->Header));
4279
    ((DR_CORE_DEVICELIST_ANNOUNCE_REQ *)res)->__destructor = &destroy_DR_CORE_DEVICELIST_ANNOUNCE_REQ;
4280
    ((DR_CORE_DEVICELIST_ANNOUNCE_REQ *)res)->in = &get_DR_CORE_DEVICELIST_ANNOUNCE_REQ;
4281
    ((DR_CORE_DEVICELIST_ANNOUNCE_REQ *)res)->out = &send_DR_CORE_DEVICELIST_ANNOUNCE_REQ;
4282
    construct_DR_CORE_DEVICELIST_ANNOUNCE_REQ(res);
4283
  }
4284
  else if (!g_strcasecmp(cname,"DR_DEVICELIST_ANNOUNCE")) {
4285
    res = (void *)g_malloc(sizeof(DR_DEVICELIST_ANNOUNCE),1);
4286
    ((DR_DEVICELIST_ANNOUNCE *)res)->Header.out = &send_RDPDR_HEADER;
4287
    ((DR_DEVICELIST_ANNOUNCE *)res)->Header.in = &get_RDPDR_HEADER;
4288
    construct_RDPDR_HEADER(&(((DR_DEVICELIST_ANNOUNCE *)res)->Header));
4289
    ((DR_DEVICELIST_ANNOUNCE *)res)->__destructor = &destroy_DR_DEVICELIST_ANNOUNCE;
4290
    ((DR_DEVICELIST_ANNOUNCE *)res)->in = &get_DR_DEVICELIST_ANNOUNCE;
4291
    ((DR_DEVICELIST_ANNOUNCE *)res)->out = &send_DR_DEVICELIST_ANNOUNCE;
4292
    construct_DR_DEVICELIST_ANNOUNCE(res);
4293
  }
4294
  else if (!g_strcasecmp(cname,"DR_DEVICELIST_REMOVE")) {
4295
    res = (void *)g_malloc(sizeof(DR_DEVICELIST_REMOVE),1);
4296
    ((DR_DEVICELIST_REMOVE *)res)->Header.out = &send_RDPDR_HEADER;
4297
    ((DR_DEVICELIST_REMOVE *)res)->Header.in = &get_RDPDR_HEADER;
4298
    construct_RDPDR_HEADER(&(((DR_DEVICELIST_REMOVE *)res)->Header));
4299
    ((DR_DEVICELIST_REMOVE *)res)->__destructor = &destroy_DR_DEVICELIST_REMOVE;
4300
    ((DR_DEVICELIST_REMOVE *)res)->in = &get_DR_DEVICELIST_REMOVE;
4301
    ((DR_DEVICELIST_REMOVE *)res)->out = &send_DR_DEVICELIST_REMOVE;
4302
    construct_DR_DEVICELIST_REMOVE(res);
4303
  }
4304
  else if (!g_strcasecmp(cname,"DR_DRIVE_CORE_DEVICE_IOREQUEST")) {
4305
    res = (void *)g_malloc(sizeof(DR_DRIVE_CORE_DEVICE_IOREQUEST),1);
4306
    ((DR_DRIVE_CORE_DEVICE_IOREQUEST *)res)->__destructor = &destroy_DR_DRIVE_CORE_DEVICE_IOREQUEST;
4307
    construct_DR_DRIVE_CORE_DEVICE_IOREQUEST(res);
4308
  }
4309
  else if (!g_strcasecmp(cname,"DR_DRIVE_CREATE_REQ")) {
4310
    res = (void *)g_malloc(sizeof(DR_DRIVE_CREATE_REQ),1);
4311
    ((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest.DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4312
    ((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest.DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4313
    construct_RDPDR_HEADER(&(((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest.DeviceIoRequest.Header));
4314
    ((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest.DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4315
    ((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest.DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4316
    construct_DR_CREATE_REQ(&(((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest));
4317
    ((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest.in = &get_DR_CREATE_REQ;
4318
    ((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest.out = &send_DR_CREATE_REQ;
4319
    construct_DR_CREATE_REQ(&(((DR_DRIVE_CREATE_REQ *)res)->DeviceCreateRequest));
4320
    ((DR_DRIVE_CREATE_REQ *)res)->__destructor = &destroy_DR_DRIVE_CREATE_REQ;
4321
    ((DR_DRIVE_CREATE_REQ *)res)->in = &get_DR_DRIVE_CREATE_REQ;
4322
    ((DR_DRIVE_CREATE_REQ *)res)->out = &send_DR_DRIVE_CREATE_REQ;
4323
    construct_DR_DRIVE_CREATE_REQ(res);
4324
  }
4325
  else if (!g_strcasecmp(cname,"DR_DRIVE_CLOSE_REQ")) {
4326
    res = (void *)g_malloc(sizeof(DR_DRIVE_CLOSE_REQ),1);
4327
    ((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest.DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4328
    ((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest.DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4329
    construct_RDPDR_HEADER(&(((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest.DeviceIoRequest.Header));
4330
    ((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest.DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4331
    ((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest.DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4332
    construct_DR_CLOSE_REQ(&(((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest));
4333
    ((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest.in = &get_DR_CLOSE_REQ;
4334
    ((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest.out = &send_DR_CLOSE_REQ;
4335
    construct_DR_CLOSE_REQ(&(((DR_DRIVE_CLOSE_REQ *)res)->DeviceCloseRequest));
4336
    ((DR_DRIVE_CLOSE_REQ *)res)->__destructor = &destroy_DR_DRIVE_CLOSE_REQ;
4337
    ((DR_DRIVE_CLOSE_REQ *)res)->in = &get_DR_DRIVE_CLOSE_REQ;
4338
    ((DR_DRIVE_CLOSE_REQ *)res)->out = &send_DR_DRIVE_CLOSE_REQ;
4339
    construct_DR_DRIVE_CLOSE_REQ(res);
4340
  }
4341
  else if (!g_strcasecmp(cname,"DR_DRIVE_READ_REQ")) {
4342
    res = (void *)g_malloc(sizeof(DR_DRIVE_READ_REQ),1);
4343
    ((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest.DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4344
    ((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest.DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4345
    construct_RDPDR_HEADER(&(((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest.DeviceIoRequest.Header));
4346
    ((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest.DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4347
    ((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest.DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4348
    construct_DR_READ_REQ(&(((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest));
4349
    ((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest.in = &get_DR_READ_REQ;
4350
    ((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest.out = &send_DR_READ_REQ;
4351
    construct_DR_READ_REQ(&(((DR_DRIVE_READ_REQ *)res)->DeviceReadRequest));
4352
    ((DR_DRIVE_READ_REQ *)res)->__destructor = &destroy_DR_DRIVE_READ_REQ;
4353
    ((DR_DRIVE_READ_REQ *)res)->out = &send_DR_DRIVE_READ_REQ;
4354
    ((DR_DRIVE_READ_REQ *)res)->in = &get_DR_DRIVE_READ_REQ;
4355
    construct_DR_DRIVE_READ_REQ(res);
4356
  }
4357
  else if (!g_strcasecmp(cname,"DR_DRIVE_WRITE_REQ")) {
4358
    res = (void *)g_malloc(sizeof(DR_DRIVE_WRITE_REQ),1);
4359
    ((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest.DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4360
    ((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest.DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4361
    construct_RDPDR_HEADER(&(((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest.DeviceIoRequest.Header));
4362
    ((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest.DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4363
    ((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest.DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4364
    construct_DR_WRITE_REQ(&(((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest));
4365
    ((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest.in = &get_DR_WRITE_REQ;
4366
    ((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest.out = &send_DR_WRITE_REQ;
4367
    construct_DR_WRITE_REQ(&(((DR_DRIVE_WRITE_REQ *)res)->DeviceWriteRequest));
4368
    ((DR_DRIVE_WRITE_REQ *)res)->__destructor = &destroy_DR_DRIVE_WRITE_REQ;
4369
    ((DR_DRIVE_WRITE_REQ *)res)->out = &send_DR_DRIVE_WRITE_REQ;
4370
    ((DR_DRIVE_WRITE_REQ *)res)->in = &get_DR_DRIVE_WRITE_REQ;
4371
    construct_DR_DRIVE_WRITE_REQ(res);
4372
  }
4373
  else if (!g_strcasecmp(cname,"DR_DRIVE_CONTROL_REQ")) {
4374
    res = (void *)g_malloc(sizeof(DR_DRIVE_CONTROL_REQ),1);
4375
    ((DR_DRIVE_CONTROL_REQ *)res)->Header.DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4376
    ((DR_DRIVE_CONTROL_REQ *)res)->Header.DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4377
    construct_RDPDR_HEADER(&(((DR_DRIVE_CONTROL_REQ *)res)->Header.DeviceIoRequest.Header));
4378
    ((DR_DRIVE_CONTROL_REQ *)res)->Header.DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4379
    ((DR_DRIVE_CONTROL_REQ *)res)->Header.DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4380
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_CONTROL_REQ *)res)->Header.DeviceIoRequest));
4381
    ((DR_DRIVE_CONTROL_REQ *)res)->Header.in = &get_DR_CONTROL_REQ;
4382
    ((DR_DRIVE_CONTROL_REQ *)res)->Header.out = &send_DR_CONTROL_REQ;
4383
    construct_DR_CONTROL_REQ(&(((DR_DRIVE_CONTROL_REQ *)res)->Header));
4384
    ((DR_DRIVE_CONTROL_REQ *)res)->__destructor = &destroy_DR_DRIVE_CONTROL_REQ;
4385
    ((DR_DRIVE_CONTROL_REQ *)res)->out = &send_DR_DRIVE_CONTROL_REQ;
4386
    ((DR_DRIVE_CONTROL_REQ *)res)->in = &get_DR_DRIVE_CONTROL_REQ;
4387
    construct_DR_DRIVE_CONTROL_REQ(res);
4388
  }
4389
  else if (!g_strcasecmp(cname,"DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ")) {
4390
    res = (void *)g_malloc(sizeof(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ),1);
4391
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4392
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4393
    construct_RDPDR_HEADER(&(((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.Header));
4394
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4395
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4396
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest));
4397
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->__destructor = &destroy_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ;
4398
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->out = &send_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ;
4399
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *)res)->in = &get_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ;
4400
    construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(res);
4401
  }
4402
  else if (!g_strcasecmp(cname,"DR_DRIVE_SET_VOLUME_INFORMATION_REQ")) {
4403
    res = (void *)g_malloc(sizeof(DR_DRIVE_SET_VOLUME_INFORMATION_REQ),1);
4404
    ((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4405
    ((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4406
    construct_RDPDR_HEADER(&(((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.Header));
4407
    ((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4408
    ((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4409
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->DeviceIoRequest));
4410
    ((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->__destructor = &destroy_DR_DRIVE_SET_VOLUME_INFORMATION_REQ;
4411
    ((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->out = &send_DR_DRIVE_SET_VOLUME_INFORMATION_REQ;
4412
    ((DR_DRIVE_SET_VOLUME_INFORMATION_REQ *)res)->in = &get_DR_DRIVE_SET_VOLUME_INFORMATION_REQ;
4413
    construct_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(res);
4414
  }
4415
  else if (!g_strcasecmp(cname,"DR_DRIVE_QUERY_INFORMATION_REQ")) {
4416
    res = (void *)g_malloc(sizeof(DR_DRIVE_QUERY_INFORMATION_REQ),1);
4417
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4418
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4419
    construct_RDPDR_HEADER(&(((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest.Header));
4420
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest.MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
4421
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest.MinorFunction = IRP_MN_QUERY_DIRECTORY;
4422
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4423
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4424
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->DeviceIoRequest));
4425
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->FsInformationClass = FileDirectoryInformation;
4426
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->__destructor = &destroy_DR_DRIVE_QUERY_INFORMATION_REQ;
4427
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->in = &get_DR_DRIVE_QUERY_INFORMATION_REQ;
4428
    ((DR_DRIVE_QUERY_INFORMATION_REQ *)res)->out = &send_DR_DRIVE_QUERY_INFORMATION_REQ;
4429
    construct_DR_DRIVE_QUERY_INFORMATION_REQ(res);
4430
  }
4431
  else if (!g_strcasecmp(cname,"DR_DRIVE_SET_INFORMATION_REQ")) {
4432
    res = (void *)g_malloc(sizeof(DR_DRIVE_SET_INFORMATION_REQ),1);
4433
    ((DR_DRIVE_SET_INFORMATION_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4434
    ((DR_DRIVE_SET_INFORMATION_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4435
    construct_RDPDR_HEADER(&(((DR_DRIVE_SET_INFORMATION_REQ *)res)->DeviceIoRequest.Header));
4436
    ((DR_DRIVE_SET_INFORMATION_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4437
    ((DR_DRIVE_SET_INFORMATION_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4438
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_SET_INFORMATION_REQ *)res)->DeviceIoRequest));
4439
    ((DR_DRIVE_SET_INFORMATION_REQ *)res)->__destructor = &destroy_DR_DRIVE_SET_INFORMATION_REQ;
4440
    ((DR_DRIVE_SET_INFORMATION_REQ *)res)->in = &get_DR_DRIVE_SET_INFORMATION_REQ;
4441
    ((DR_DRIVE_SET_INFORMATION_REQ *)res)->out = &send_DR_DRIVE_SET_INFORMATION_REQ;
4442
    construct_DR_DRIVE_SET_INFORMATION_REQ(res);
4443
  }
4444
  else if (!g_strcasecmp(cname,"RDP_FILE_RENAME_INFORMATION")) {
4445
    res = (void *)g_malloc(sizeof(RDP_FILE_RENAME_INFORMATION),1);
4446
    construct_RDP_FILE_RENAME_INFORMATION(res);
4447
  }
4448
  else if (!g_strcasecmp(cname,"DR_DRIVE_QUERY_DIRECTORY_REQ")) {
4449
    res = (void *)g_malloc(sizeof(DR_DRIVE_QUERY_DIRECTORY_REQ),1);
4450
    ((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4451
    ((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4452
    construct_RDPDR_HEADER(&(((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->DeviceIoRequest.Header));
4453
    ((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4454
    ((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4455
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->DeviceIoRequest));
4456
    ((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->__destructor = &destroy_DR_DRIVE_QUERY_DIRECTORY_REQ;
4457
    ((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->in = &get_DR_DRIVE_QUERY_DIRECTORY_REQ;
4458
    ((DR_DRIVE_QUERY_DIRECTORY_REQ *)res)->out = &send_DR_DRIVE_QUERY_DIRECTORY_REQ;
4459
    construct_DR_DRIVE_QUERY_DIRECTORY_REQ(res);
4460
  }
4461
  else if (!g_strcasecmp(cname,"DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ")) {
4462
    res = (void *)g_malloc(sizeof(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ),1);
4463
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4464
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4465
    construct_RDPDR_HEADER(&(((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->DeviceIoRequest.Header));
4466
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4467
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4468
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->DeviceIoRequest));
4469
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->__destructor = &destroy_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ;
4470
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->in = &get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ;
4471
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *)res)->out = &send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ;
4472
    construct_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(res);
4473
  }
4474
  else if (!g_strcasecmp(cname,"DR_DRIVE_LOCK_REQ")) {
4475
    res = (void *)g_malloc(sizeof(DR_DRIVE_LOCK_REQ),1);
4476
    ((DR_DRIVE_LOCK_REQ *)res)->DeviceIoRequest.Header.in = &get_RDPDR_HEADER;
4477
    ((DR_DRIVE_LOCK_REQ *)res)->DeviceIoRequest.Header.out = &send_RDPDR_HEADER;
4478
    construct_RDPDR_HEADER(&(((DR_DRIVE_LOCK_REQ *)res)->DeviceIoRequest.Header));
4479
    ((DR_DRIVE_LOCK_REQ *)res)->DeviceIoRequest.in = &get_DR_DEVICE_IOREQUEST;
4480
    ((DR_DRIVE_LOCK_REQ *)res)->DeviceIoRequest.out = &send_DR_DEVICE_IOREQUEST;
4481
    construct_DR_DEVICE_IOREQUEST(&(((DR_DRIVE_LOCK_REQ *)res)->DeviceIoRequest));
4482
    ((DR_DRIVE_LOCK_REQ *)res)->__destructor = &destroy_DR_DRIVE_LOCK_REQ;
4483
    ((DR_DRIVE_LOCK_REQ *)res)->in = &get_DR_DRIVE_LOCK_REQ;
4484
    ((DR_DRIVE_LOCK_REQ *)res)->out = &send_DR_DRIVE_LOCK_REQ;
4485
    construct_DR_DRIVE_LOCK_REQ(res);
4486
  }
4487
  else if (!g_strcasecmp(cname,"DR_DRIVE_CORE_DEVICE_IOCOMPLETION")) {
4488
    res = (void *)g_malloc(sizeof(DR_DRIVE_CORE_DEVICE_IOCOMPLETION),1);
4489
    ((DR_DRIVE_CORE_DEVICE_IOCOMPLETION *)res)->__destructor = &destroy_DR_DRIVE_CORE_DEVICE_IOCOMPLETION;
4490
    construct_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(res);
4491
  }
4492
  else if (!g_strcasecmp(cname,"DR_DRIVE_CREATE_RSP")) {
4493
    res = (void *)g_malloc(sizeof(DR_DRIVE_CREATE_RSP),1);
4494
    ((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4495
    ((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4496
    construct_RDPDR_HEADER(&(((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.DeviceIoReply.Header));
4497
    ((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4498
    ((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4499
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.DeviceIoReply));
4500
    ((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.in = &get_DR_CREATE_RSP;
4501
    ((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse.out = &send_DR_CREATE_RSP;
4502
    construct_DR_CREATE_RSP(&(((DR_DRIVE_CREATE_RSP *)res)->DeviceCreateResponse));
4503
    ((DR_DRIVE_CREATE_RSP *)res)->__destructor = &destroy_DR_DRIVE_CREATE_RSP;
4504
    ((DR_DRIVE_CREATE_RSP *)res)->in = &get_DR_DRIVE_CREATE_RSP;
4505
    ((DR_DRIVE_CREATE_RSP *)res)->out = &send_DR_DRIVE_CREATE_RSP;
4506
    construct_DR_DRIVE_CREATE_RSP(res);
4507
  }
4508
  else if (!g_strcasecmp(cname,"DR_DRIVE_CLOSE_RSP")) {
4509
    res = (void *)g_malloc(sizeof(DR_DRIVE_CLOSE_RSP),1);
4510
    ((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4511
    ((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4512
    construct_RDPDR_HEADER(&(((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.DeviceIoReply.Header));
4513
    ((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4514
    ((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4515
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.DeviceIoReply));
4516
    ((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.in = &get_DR_CLOSE_RSP;
4517
    ((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse.out = &send_DR_CLOSE_RSP;
4518
    construct_DR_CLOSE_RSP(&(((DR_DRIVE_CLOSE_RSP *)res)->DeviceCloseResponse));
4519
    ((DR_DRIVE_CLOSE_RSP *)res)->__destructor = &destroy_DR_DRIVE_CLOSE_RSP;
4520
    ((DR_DRIVE_CLOSE_RSP *)res)->in = &get_DR_DRIVE_CLOSE_RSP;
4521
    ((DR_DRIVE_CLOSE_RSP *)res)->out = &send_DR_DRIVE_CLOSE_RSP;
4522
    construct_DR_DRIVE_CLOSE_RSP(res);
4523
  }
4524
  else if (!g_strcasecmp(cname,"DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP")) {
4525
    res = (void *)g_malloc(sizeof(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP),1);
4526
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4527
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4528
    construct_RDPDR_HEADER(&(((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.Header));
4529
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4530
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4531
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply));
4532
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->__destructor = &destroy_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP;
4533
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->in = &get_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP;
4534
    ((DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)res)->out = &send_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP;
4535
    construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(res);
4536
  }
4537
  else if (!g_strcasecmp(cname,"DR_DRIVE_SET_VOLUME_INFORMATION_RSP")) {
4538
    res = (void *)g_malloc(sizeof(DR_DRIVE_SET_VOLUME_INFORMATION_RSP),1);
4539
    ((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4540
    ((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4541
    construct_RDPDR_HEADER(&(((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.Header));
4542
    ((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4543
    ((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4544
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->DeviceIoReply));
4545
    ((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->__destructor = &destroy_DR_DRIVE_SET_VOLUME_INFORMATION_RSP;
4546
    ((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->in = &get_DR_DRIVE_SET_VOLUME_INFORMATION_RSP;
4547
    ((DR_DRIVE_SET_VOLUME_INFORMATION_RSP *)res)->out = &send_DR_DRIVE_SET_VOLUME_INFORMATION_RSP;
4548
    construct_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(res);
4549
  }
4550
  else if (!g_strcasecmp(cname,"DR_DRIVE_QUERY_INFORMATION_RSP")) {
4551
    res = (void *)g_malloc(sizeof(DR_DRIVE_QUERY_INFORMATION_RSP),1);
4552
    ((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4553
    ((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4554
    construct_RDPDR_HEADER(&(((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->DeviceIoReply.Header));
4555
    ((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4556
    ((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4557
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->DeviceIoReply));
4558
    ((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->__destructor = &destroy_DR_DRIVE_QUERY_INFORMATION_RSP;
4559
    ((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->in = &get_DR_DRIVE_QUERY_INFORMATION_RSP;
4560
    ((DR_DRIVE_QUERY_INFORMATION_RSP *)res)->out = &send_DR_DRIVE_QUERY_INFORMATION_RSP;
4561
    construct_DR_DRIVE_QUERY_INFORMATION_RSP(res);
4562
  }
4563
  else if (!g_strcasecmp(cname,"DR_DRIVE_QUERY_DIRECTORY_RSP")) {
4564
    res = (void *)g_malloc(sizeof(DR_DRIVE_QUERY_DIRECTORY_RSP),1);
4565
    ((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4566
    ((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4567
    construct_RDPDR_HEADER(&(((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->DeviceIoReply.Header));
4568
    ((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4569
    ((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4570
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->DeviceIoReply));
4571
    ((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->__destructor = &destroy_DR_DRIVE_QUERY_DIRECTORY_RSP;
4572
    ((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->in = &get_DR_DRIVE_QUERY_DIRECTORY_RSP;
4573
    ((DR_DRIVE_QUERY_DIRECTORY_RSP *)res)->out = &send_DR_DRIVE_QUERY_DIRECTORY_RSP;
4574
    construct_DR_DRIVE_QUERY_DIRECTORY_RSP(res);
4575
  }
4576
  else if (!g_strcasecmp(cname,"DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP")) {
4577
    res = (void *)g_malloc(sizeof(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP),1);
4578
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4579
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4580
    construct_RDPDR_HEADER(&(((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->DeviceIoReply.Header));
4581
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4582
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4583
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->DeviceIoReply));
4584
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->__destructor = &destroy_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP;
4585
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->in = &get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP;
4586
    ((DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *)res)->out = &send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP;
4587
    construct_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(res);
4588
  }
4589
  else if (!g_strcasecmp(cname,"DR_DRIVE_LOCK_RSP")) {
4590
    res = (void *)g_malloc(sizeof(DR_DRIVE_LOCK_RSP),1);
4591
    ((DR_DRIVE_LOCK_RSP *)res)->DeviceIoReply.Header.in = &get_RDPDR_HEADER;
4592
    ((DR_DRIVE_LOCK_RSP *)res)->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
4593
    construct_RDPDR_HEADER(&(((DR_DRIVE_LOCK_RSP *)res)->DeviceIoReply.Header));
4594
    ((DR_DRIVE_LOCK_RSP *)res)->DeviceIoReply.in = &get_DR_DEVICE_IOCOMPLETION;
4595
    ((DR_DRIVE_LOCK_RSP *)res)->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
4596
    construct_DR_DEVICE_IOCOMPLETION(&(((DR_DRIVE_LOCK_RSP *)res)->DeviceIoReply));
4597
    ((DR_DRIVE_LOCK_RSP *)res)->__destructor = &destroy_DR_DRIVE_LOCK_RSP;
4598
    ((DR_DRIVE_LOCK_RSP *)res)->in = &get_DR_DRIVE_LOCK_RSP;
4599
    ((DR_DRIVE_LOCK_RSP *)res)->out = &send_DR_DRIVE_LOCK_RSP;
4600
    construct_DR_DRIVE_LOCK_RSP(res);
4601
  }
4602
  else if (!g_strcasecmp(cname,"DR_CORE_USER_LOGGEDON")) {
4603
    res = (void *)g_malloc(sizeof(DR_CORE_USER_LOGGEDON),1);
4604
    ((DR_CORE_USER_LOGGEDON *)res)->Header.in = &get_RDPDR_HEADER;
4605
    ((DR_CORE_USER_LOGGEDON *)res)->Header.out = &send_RDPDR_HEADER;
4606
    construct_RDPDR_HEADER(&(((DR_CORE_USER_LOGGEDON *)res)->Header));
4607
    ((DR_CORE_USER_LOGGEDON *)res)->__destructor = &destroy_DR_CORE_USER_LOGGEDON;
4608
    ((DR_CORE_USER_LOGGEDON *)res)->in = &get_DR_CORE_USER_LOGGEDON;
4609
    ((DR_CORE_USER_LOGGEDON *)res)->out = &send_DR_CORE_USER_LOGGEDON;
4610
    construct_DR_CORE_USER_LOGGEDON(res);
4611
  }
4612
  else if (!g_strcasecmp(cname,"DYNVC_CAPS_VERSION1")) {
4613
    res = (void *)g_malloc(sizeof(DYNVC_CAPS_VERSION1),1);
4614
    construct_DYNVC_CAPS_VERSION1(res);
4615
  }
4616
  else if (!g_strcasecmp(cname,"DYNVC_CAPS_VERSION2")) {
4617
    res = (void *)g_malloc(sizeof(DYNVC_CAPS_VERSION2),1);
4618
    construct_DYNVC_CAPS_VERSION2(res);
4619
  }
4620
  else if (!g_strcasecmp(cname,"DYNVC_CAPS_RSP")) {
4621
    res = (void *)g_malloc(sizeof(DYNVC_CAPS_RSP),1);
4622
    construct_DYNVC_CAPS_RSP(res);
4623
  }
4624
  else if (!g_strcasecmp(cname,"DYNVC_CREATE_REQ")) {
4625
    res = (void *)g_malloc(sizeof(DYNVC_CREATE_REQ) + 50,1);
4626
    construct_DYNVC_CREATE_REQ(res);
4627
  }
4628
  else if (!g_strcasecmp(cname,"DYNVC_CREATE_RSP")) {
4629
    res = (void *)g_malloc(sizeof(DYNVC_CREATE_RSP),1);
4630
    construct_DYNVC_CREATE_RSP(res);
4631
  }
4632
  else if (!g_strcasecmp(cname,"DYNVC_DATA_FIRST")) {
4633
    res = (void *)g_malloc(sizeof(DYNVC_DATA_FIRST) + 1600,1);
4634
    construct_DYNVC_DATA_FIRST(res);
4635
  }
4636
  else if (!g_strcasecmp(cname,"DYNVC_DATA")) {
4637
    res = (void *)g_malloc(sizeof(DYNVC_DATA) + 1600,1);
4638
    construct_DYNVC_DATA(res);
4639
  }
4640
  else if (!g_strcasecmp(cname,"DYNVC_CLOSE")) {
4641
    res = (void *)g_malloc(sizeof(DYNVC_CLOSE),1);
4642
    construct_DYNVC_CLOSE(res);
4643
  }
4644
  
4645
  return res;
4646
}
4647
4648
/*****************************************************************************/
4649
static int APP_CC setPath_DR_DRIVE_QUERY_DIRECTORY_REQ(struct _DR_DRIVE_QUERY_DIRECTORY_REQ * self, const char * pn) {
4650
  int rv = 0;
4651
  int idx = 0;
4652
  int lmt = 0;
4653
4654
  g_memset(self->Path,0x00,sizeof(BYTE) * 512);
4655
  lmt = g_strlen(pn);
4656
  if ((pn != NULL) && (lmt > 0)) {
4657
    if (lmt > 255) {
4658
      lmt = 255;
4659
    }
4660
    for (idx = 0; idx < lmt; idx++) {
4661
      self->Path[(idx * 2)] = pn[idx];
4662
    }
4663
    self->PathLength = lmt * 2;
4664
  }
4665
  else {
4666
    self->PathLength = 2;
4667
  }
4668
4669
  return rv;
4670
}
4671
4672
int APP_CC send_MSG_SNDIN_VERSION(MSG_SNDIN_VERSION * self, struct stream * s) {
4673
    int rv = 0;
4674
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4675
      rv = -1;
4676
    }
4677
    else {
4678
      out_uint8(s, self->Header.MessageId);
4679
      out_uint32_le(s, self->Version);
4680
    }
4681
    return rv;
4682
}
4683
4684
int APP_CC get_MSG_SNDIN_VERSION(MSG_SNDIN_VERSION * self, struct stream * s) {
4685
    int rv = 0;
4686
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4687
      rv = -1;
4688
    }
4689
    else {
4690
      in_uint8(s, self->Header.MessageId);
4691
      in_uint32_le(s, self->Version);
4692
    }
4693
    return rv;
4694
}
4695
4696
int APP_CC send_MSG_SNDIN_FORMATS(MSG_SNDIN_FORMATS * self, struct stream * s) {
4697
    int rv = 0;
4698
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4699
	rv = -1;
4700
    }
4701
    else {
4702
	ptrdiff_t i = 0;
4703
	out_uint8(s, self->Header.MessageId);
4704
	out_uint32_le(s, self->NumFormats);
4705
	out_uint32_le(s, self->cbSizeFormatsPacket);
4706
	if (self->NumFormats > 0) for (i = 0; i < self->NumFormats; i++) {
4707
	  AUDIO_FORMAT_REC * fmt = (AUDIO_FORMAT_REC *)(&(self->SoundFormats[i]));
4708
	  out_uint16_le(s, fmt->wFormatTag);
4709
	  out_uint16_le(s, fmt->nChannels);
4710
	  out_uint32_le(s, fmt->nSamplesPerSec);
4711
	  out_uint32_le(s, fmt->nAvgBytesPerSec);
4712
	  out_uint16_le(s, fmt->nBlockAlign);
4713
	  out_uint16_le(s, fmt->wBitsPerSample);
4714
	  out_uint16_le(s, fmt->cbSize);
4715
	  if (fmt->cbSize > 0 && fmt->data != NULL) {
4716
	    out_uint8a(s, fmt->data, fmt->cbSize);
4717
	  }
4718
	}
4719
    }
4720
    return rv;
4721
}
4722
4723
int APP_CC get_MSG_SNDIN_FORMATS(MSG_SNDIN_FORMATS * self, struct stream * s) {
4724
  int rv = 0;
4725
  if (self == NULL || s == NULL) {
4726
    rv = -1;
4727
  }
4728
  else {
4729
    in_uint8(s, self->Header.MessageId);
4730
    in_uint32_le(s, self->NumFormats);
4731
    in_uint32_le(s, self->cbSizeFormatsPacket);
4732
    if (self->NumFormats > 0 && self->cbSizeFormatsPacket > 0) {
4733
      in_uint8a(s, self->SoundFormats, self->cbSizeFormatsPacket);
4734
    }
4735
  }
4736
  return rv;
4737
}
4738
4739
int APP_CC send_MSG_SNDIN_OPEN(MSG_SNDIN_OPEN * self, struct stream * s) {
4740
    int rv = 0;
4741
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4742
	rv = -1;
4743
    }
4744
    else {
4745
	out_uint8(s, self->Header.MessageId);
4746
	out_uint32_le(s, self->FramesPerPacket);
4747
	out_uint32_le(s, self->initialFormat);
4748
	out_uint16_le(s, self->wFormatTag);
4749
	out_uint16_le(s, self->nChannels);
4750
	out_uint32_le(s, self->nSamplesPerSec);
4751
	out_uint32_le(s, self->nAvgBytesPerSec);
4752
	out_uint16_le(s, self->nBlockAlign);
4753
	out_uint16_le(s, self->wBitsPerSample);
4754
	out_uint16_le(s, self->cbSize);
4755
	if (self->cbSize > 0) {
4756
	    out_uint8a(s, self->ExtraFormatData, self->cbSize);
4757
	}
4758
    }
4759
    return rv;
4760
}
4761
4762
int APP_CC get_MSG_SNDIN_OPEN(MSG_SNDIN_OPEN * self, struct stream * s) {
4763
    int rv = 0;
4764
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4765
	rv = -1;
4766
    }
4767
    else {
4768
	in_uint8(s, self->Header.MessageId);
4769
	in_uint32_le(s, self->FramesPerPacket);
4770
	in_uint32_le(s, self->initialFormat);
4771
	in_uint16_le(s, self->wFormatTag);
4772
	in_uint16_le(s, self->nChannels);
4773
	in_uint32_le(s, self->nSamplesPerSec);
4774
	in_uint32_le(s, self->nAvgBytesPerSec);
4775
	in_uint16_le(s, self->nBlockAlign);
4776
	in_uint16_le(s, self->wBitsPerSample);
4777
	in_uint16_le(s, self->cbSize);
4778
	if (self->cbSize > 0) {
4779
	    in_uint8a(s, self->ExtraFormatData, self->cbSize);
4780
	}
4781
    }
4782
    return rv;
4783
}
4784
4785
int APP_CC send_MSG_SNDIN_OPEN_REPLY(MSG_SNDIN_OPEN_REPLY * self, struct stream * s) {
4786
    int rv = 0;
4787
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4788
	rv = -1;
4789
    }
4790
    else {
4791
	out_uint8(s, self->Header.MessageId);
4792
	out_uint32_le(s, self->Result);
4793
    }
4794
    return rv;
4795
}
4796
4797
int APP_CC get_MSG_SNDIN_OPEN_REPLY(MSG_SNDIN_OPEN_REPLY * self, struct stream * s) {
4798
    int rv = 0;
4799
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4800
	rv = -1;
4801
    }
4802
    else {
4803
	in_uint8(s, self->Header.MessageId);
4804
	in_uint32_le(s, self->Result);
4805
    }
4806
    return rv;
4807
}
4808
4809
int APP_CC send_MSG_SNDIN_DATA_INCOMING(MSG_SNDIN_DATA_INCOMING * self, struct stream * s) {
4810
    int rv = 0;
4811
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4812
	rv = -1;
4813
    }
4814
    else {
4815
	out_uint8(s, self->Header.MessageId);
4816
    }
4817
    return rv;
4818
}
4819
4820
int APP_CC get_MSG_SNDIN_DATA_INCOMING(MSG_SNDIN_DATA_INCOMING * self, struct stream * s) {
4821
    int rv = 0;
4822
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4823
	rv = -1;
4824
    }
4825
    else {
4826
	in_uint8(s, self->Header.MessageId);
4827
    }
4828
    return rv;
4829
}
4830
4831
int APP_CC send_MSG_SNDIN_DATA(MSG_SNDIN_DATA * self, struct stream * s) {
4832
    int rv = 0;
4833
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL || self->len < 1) {
4834
	rv = -1;
4835
    }
4836
    else {
4837
	out_uint8(s, self->Header.MessageId);
4838
	out_uint8a(s, self->Data, self->len);
4839
    }
4840
    return rv;
4841
}
4842
4843
int APP_CC get_MSG_SNDIN_DATA(MSG_SNDIN_DATA * self, struct stream * s) {
4844
    int rv = 0;
4845
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4846
	rv = -1;
4847
    }
4848
    else {
4849
	in_uint8(s, self->Header.MessageId);
4850
	if (s->end > s->p) {
4851
	    self->len = s->end - s->p;
4852
	    in_uint8a(s, self->Data, self->len);
4853
	}
4854
    }
4855
    return rv;
4856
}
4857
4858
int APP_CC send_MSG_SNDIN_FORMATCHANGE(MSG_SNDIN_FORMATCHANGE * self, struct stream * s) {
4859
    int rv = 0;
4860
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4861
	rv = -1;
4862
    }
4863
    else {
4864
	out_uint8(s, self->Header.MessageId);
4865
	out_uint32_le(s, self->NewFormat);
4866
    }
4867
    return rv;
4868
}
4869
4870
int APP_CC get_MSG_SNDIN_FORMATCHANGE(MSG_SNDIN_FORMATCHANGE * self, struct stream * s) {
4871
    int rv = 0;
4872
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4873
	rv = -1;
4874
    }
4875
    else {
4876
	in_uint8(s, self->Header.MessageId);
4877
	in_uint32_le(s, self->NewFormat);
4878
    }
4879
    return rv;
4880
}
4881
4882
int APP_CC send_WAVEFORMAT_EXTENSIBLE(WAVEFORMAT_EXTENSIBLE * self, struct stream * s) {
4883
    int rv = 0;
4884
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4885
	rv = -1;
4886
    }
4887
    else {
4888
	out_uint16_le(s, self->wValidBitsPerSample);
4889
	out_uint32_le(s, self->dwChannelMask);
4890
	/* GUID */
4891
	out_uint32_le(s, self->SubFormat.f1);
4892
	out_uint16_le(s, self->SubFormat.f2);
4893
	out_uint16_le(s, self->SubFormat.f3);
4894
	out_uint8(s, self->SubFormat.f4[0]);
4895
	out_uint8(s, self->SubFormat.f4[1]);
4896
	out_uint8(s, self->SubFormat.f4[2]);
4897
	out_uint8(s, self->SubFormat.f4[3]);
4898
	out_uint8(s, self->SubFormat.f4[4]);
4899
	out_uint8(s, self->SubFormat.f4[5]);
4900
	out_uint8(s, self->SubFormat.f4[6]);
4901
	out_uint8(s, self->SubFormat.f4[7]);
4902
    }
4903
    return rv;
4904
}
4905
4906
int APP_CC get_WAVEFORMAT_EXTENSIBLE(WAVEFORMAT_EXTENSIBLE * self, struct stream * s) {
4907
    int rv = 0;
4908
    if (self == NULL || s == NULL || s->data == NULL || s->p == NULL) {
4909
	rv = -1;
4910
    }
4911
    else {
4912
	in_uint16_le(s, self->wValidBitsPerSample);
4913
	in_uint32_le(s, self->dwChannelMask);
4914
	/* GUID */
4915
	in_uint32_le(s, self->SubFormat.f1);
4916
	in_uint16_le(s, self->SubFormat.f2);
4917
	in_uint16_le(s, self->SubFormat.f3);
4918
	in_uint8(s, self->SubFormat.f4[0]);
4919
	in_uint8(s, self->SubFormat.f4[1]);
4920
	in_uint8(s, self->SubFormat.f4[2]);
4921
	in_uint8(s, self->SubFormat.f4[3]);
4922
	in_uint8(s, self->SubFormat.f4[4]);
4923
	in_uint8(s, self->SubFormat.f4[5]);
4924
	in_uint8(s, self->SubFormat.f4[6]);
4925
	in_uint8(s, self->SubFormat.f4[7]);
4926
    }
4927
    return rv;
4928
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/rdpdr_methods.h (+372 lines)
Line 0    Link Here 
1
#if !defined(__XRDP_RDPDR_METHODS__)
2
#define __XRDP_RDPDR_METHODS__
3
4
5
#include "os_calls.h"
6
#include "rdpdr.h"
7
#include "thread_calls.h"
8
#include "thread_macros.h"
9
#include "trans.h"
10
11
12
13
/**************************************************************************
14
 *
15
 *	macros
16
 */
17
18
#define RDPDR_NEW(c) (c *)rdpdr_inst(#c)
19
#define RDPDR_FREE(itm) {			 \
20
  if (itm != NULL) {				 \
21
    if ( (*itm->__destructor) != NULL ) {	 \
22
      (*itm->__destructor)((void *)itm);	 \
23
    }						 \
24
    itm = NULL; 				 \
25
  }						 \
26
}
27
28
29
30
/**************************************************************************
31
 *
32
 *	global variables
33
 */
34
35
36
/**************************************************************************
37
 *
38
 *	constructors
39
 */
40
41
int APP_CC construct_RDPDR_HEADER(RDPDR_HEADER *);
42
int APP_CC construct_CAPABILITY_HEADER(CAPABILITY_HEADER *);
43
int APP_CC construct_CAPABILITY_SET(CAPABILITY_SET *);
44
int APP_CC construct_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE *);
45
int APP_CC construct_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST *);
46
int APP_CC construct_DR_CREATE_REQ(DR_CREATE_REQ *);
47
int APP_CC construct_DR_CLOSE_REQ(DR_CLOSE_REQ *);
48
int APP_CC construct_DR_READ_REQ(DR_READ_REQ *);
49
int APP_CC construct_DR_WRITE_REQ(DR_WRITE_REQ *);
50
int APP_CC construct_DR_CONTROL_REQ(DR_CONTROL_REQ *);
51
int APP_CC construct_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *);
52
int APP_CC construct_DR_CREATE_RSP(DR_CREATE_RSP *);
53
int APP_CC construct_DR_CLOSE_RSP(DR_CLOSE_RSP *);
54
int APP_CC construct_DR_READ_RSP(DR_READ_RSP *);
55
int APP_CC construct_DR_WRITE_RSP(DR_WRITE_RSP *);
56
int APP_CC construct_DR_CONTROL_RSP(DR_CONTROL_RSP *);
57
int APP_CC construct_RDP_LOCK_INFO(RDP_LOCK_INFO *);
58
int APP_CC construct_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP *);
59
int APP_CC construct_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ *);
60
int APP_CC construct_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP *);
61
int APP_CC construct_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ *);
62
int APP_CC construct_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM *);
63
int APP_CC construct_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ *);
64
int APP_CC construct_GENERAL_CAPS_SET(GENERAL_CAPS_SET *);
65
int APP_CC construct_PRINTER_CAPS_SET(PRINTER_CAPS_SET *);
66
int APP_CC construct_PORT_CAPS_SET(PORT_CAPS_SET *);
67
int APP_CC construct_DRIVE_CAPS_SET(DRIVE_CAPS_SET *);
68
int APP_CC construct_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET *);
69
int APP_CC construct_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ *);
70
int APP_CC construct_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE *);
71
int APP_CC construct_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE *);
72
int APP_CC construct_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST *);
73
int APP_CC construct_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ *);
74
int APP_CC construct_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ *);
75
int APP_CC construct_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ *);
76
int APP_CC construct_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ *);
77
int APP_CC construct_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ *);
78
int APP_CC construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *);
79
int APP_CC construct_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ *);
80
int APP_CC construct_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ *);
81
int APP_CC construct_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ *);
82
int APP_CC construct_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION *);
83
int APP_CC construct_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ *);
84
int APP_CC construct_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *);
85
int APP_CC construct_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ *);
86
int APP_CC construct_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION *);
87
int APP_CC construct_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *);
88
int APP_CC construct_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP *);
89
int APP_CC construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *);
90
int APP_CC construct_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP *);
91
int APP_CC construct_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP *);
92
int APP_CC construct_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP *);
93
int APP_CC construct_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *);
94
int APP_CC construct_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP *);
95
int APP_CC construct_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON *);
96
int APP_CC construct_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP *);
97
int APP_CC construct_DR_DRIVE_SET_INFORMATION_RSP(DR_DRIVE_SET_INFORMATION_RSP *);
98
int APP_CC construct_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 *);
99
int APP_CC construct_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 *);
100
int APP_CC construct_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP *);
101
int APP_CC construct_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ *);
102
int APP_CC construct_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP *);
103
int APP_CC construct_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST *);
104
int APP_CC construct_DYNVC_DATA(DYNVC_DATA *);
105
int APP_CC construct_DYNVC_CLOSE(DYNVC_CLOSE *);
106
int APP_CC construct_MSG_SNDIN_VERSION(MSG_SNDIN_VERSION *);
107
int APP_CC construct_MSG_SNDIN_FORMATS(MSG_SNDIN_FORMATS *);
108
int APP_CC construct_MSG_SNDIN_OPEN(MSG_SNDIN_OPEN *);
109
int APP_CC construct_WAVEFORMAT_EXTENSIBLE(WAVEFORMAT_EXTENSIBLE *);
110
int APP_CC construct_MSG_SNDIN_OPEN_REPLY(MSG_SNDIN_OPEN_REPLY *);
111
int APP_CC construct_MSG_SNDIN_DATA_INCOMING(MSG_SNDIN_DATA_INCOMING *);
112
int APP_CC construct_MSG_SNDIN_DATA(MSG_SNDIN_DATA *);
113
int APP_CC construct_MSG_SNDIN_FORMATCHANGE(MSG_SNDIN_FORMATCHANGE *);
114
115
/*
116
int APP_CC send_( *);
117
int APP_CC get_( *);
118
*/
119
120
121
/**************************************************************************
122
 *
123
 *	senders / receivers (serializers)
124
 */
125
126
int APP_CC get_FILE_BOTH_DIR_INFORMATION(FILE_BOTH_DIR_INFORMATION *, struct stream *);
127
int APP_CC send_FILE_BOTH_DIR_INFORMATION(FILE_BOTH_DIR_INFORMATION *, struct stream *);
128
int APP_CC send_RDPDR_HEADER(RDPDR_HEADER *, struct stream *);
129
int APP_CC get_RDPDR_HEADER(RDPDR_HEADER *, struct stream *);
130
int APP_CC send_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ *, struct stream *);
131
int APP_CC get_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP *, struct stream *);
132
int APP_CC get_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ *, struct stream *);
133
int APP_CC send_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON *, struct stream *);
134
int APP_CC get_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON *, struct stream *);
135
int APP_CC send_CAPABILITY_HEADER(CAPABILITY_HEADER *, struct stream *);
136
int APP_CC get_CAPABILITY_HEADER(CAPABILITY_HEADER *, struct stream *);
137
int APP_CC send_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST *, struct stream *);
138
int APP_CC get_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST *, struct stream *);
139
int APP_CC send_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *, struct stream *);
140
int APP_CC get_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *, struct stream *);
141
int APP_CC send_DR_CREATE_REQ(DR_CREATE_REQ *, struct stream *);
142
int APP_CC get_DR_CREATE_REQ(DR_CREATE_REQ *, struct stream *);
143
int APP_CC send_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ *, struct stream *);
144
int APP_CC get_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ *, struct stream *);
145
int APP_CC send_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *, struct stream *);
146
int APP_CC get_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *, struct stream *);
147
int APP_CC send_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ *, struct stream *);
148
int APP_CC get_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ *, struct stream *);
149
int APP_CC send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *, struct stream *);
150
int APP_CC get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *, struct stream *);
151
int APP_CC send_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP *, struct stream *);
152
int APP_CC get_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP *, struct stream *);
153
int APP_CC get_CAPABILITY_SET(CAPABILITY_SET *, struct stream *);
154
int APP_CC get_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE *, struct stream *);
155
int APP_CC get_DR_CLOSE_REQ(DR_CLOSE_REQ *, struct stream *);
156
int APP_CC get_DR_READ_REQ(DR_READ_REQ *, struct stream *);
157
int APP_CC get_DR_WRITE_REQ(DR_WRITE_REQ *, struct stream *);
158
int APP_CC get_DR_CONTROL_REQ(DR_CONTROL_REQ *, struct stream *);
159
int APP_CC get_DR_CREATE_RSP(DR_CREATE_RSP *, struct stream *);
160
int APP_CC get_DR_CLOSE_RSP(DR_CLOSE_RSP *, struct stream *);
161
int APP_CC get_DR_READ_RSP(DR_READ_RSP *, struct stream *);
162
int APP_CC get_DR_WRITE_RSP(DR_WRITE_RSP *, struct stream *);
163
int APP_CC get_DR_CONTROL_RSP(DR_CONTROL_RSP *, struct stream *);
164
int APP_CC get_RDP_LOCK_INFO(RDP_LOCK_INFO *, struct stream *);
165
int APP_CC get_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP *, struct stream *);
166
int APP_CC get_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ *, struct stream *);
167
int APP_CC get_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM *, struct stream *);
168
int APP_CC get_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ *, struct stream *);
169
int APP_CC get_GENERAL_CAPS_SET(GENERAL_CAPS_SET *, struct stream *);
170
int APP_CC get_PRINTER_CAPS_SET(PRINTER_CAPS_SET *, struct stream *);
171
int APP_CC get_PORT_CAPS_SET(PORT_CAPS_SET *, struct stream *);
172
int APP_CC get_DRIVE_CAPS_SET(DRIVE_CAPS_SET *, struct stream *);
173
int APP_CC get_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET *, struct stream *);
174
int APP_CC get_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ *, struct stream *);
175
int APP_CC get_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE *, struct stream *);
176
int APP_CC get_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE *, struct stream *);
177
int APP_CC get_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST *, struct stream *);
178
int APP_CC get_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ *, struct stream *);
179
int APP_CC get_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ *, struct stream *);
180
int APP_CC get_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ *, struct stream *);
181
int APP_CC get_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ *, struct stream *);
182
int APP_CC get_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ *, struct stream *);
183
int APP_CC get_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ *, struct stream *);
184
int APP_CC get_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ *, struct stream *);
185
int APP_CC get_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION *, struct stream *);
186
int APP_CC get_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ *, struct stream *);
187
int APP_CC get_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION *, struct stream *);
188
int APP_CC get_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *, struct stream *);
189
int APP_CC get_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP *, struct stream *);
190
int APP_CC get_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *, struct stream *);
191
int APP_CC get_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP *, struct stream *);
192
int APP_CC get_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP *, struct stream *);
193
int APP_CC get_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *, struct stream *);
194
int APP_CC get_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP *, struct stream *);
195
int APP_CC get_FILE_NAME_INFORMATION(FILE_NAME_INFORMATION *, struct stream *);
196
int APP_CC get_FILE_BASIC_INFORMATION(FILE_BASIC_INFORMATION *, struct stream *);
197
int APP_CC get_FILE_STANDARD_INFORMATION(FILE_STANDARD_INFORMATION *, struct stream *);
198
int APP_CC get_FILE_ALL_INFORMATION(FILE_ALL_INFORMATION *, struct stream *);
199
int APP_CC get_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP *, struct stream *);
200
int APP_CC get_DR_DRIVE_SET_INFORMATION_RSP(DR_DRIVE_SET_INFORMATION_RSP *, struct stream *);
201
int APP_CC get_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 *, struct stream *);
202
int APP_CC get_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 *, struct stream *);
203
int APP_CC get_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP *, struct stream *);
204
int APP_CC get_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ *, struct stream *);
205
int APP_CC get_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP *, struct stream *);
206
int APP_CC get_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST *, struct stream *);
207
int APP_CC get_DYNVC_DATA(DYNVC_DATA *, struct stream *);
208
int APP_CC get_DYNVC_CLOSE(DYNVC_CLOSE *, struct stream *);
209
int APP_CC send_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 *, struct stream *);
210
int APP_CC send_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 *, struct stream *);
211
int APP_CC send_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ *, struct stream *);
212
int APP_CC send_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP *, struct stream *);
213
int APP_CC send_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST *, struct stream *);
214
int APP_CC send_DYNVC_DATA(DYNVC_DATA *, struct stream *);
215
int APP_CC send_DYNVC_CLOSE(DYNVC_CLOSE *, struct stream *);
216
int APP_CC send_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP *, struct stream *);
217
int APP_CC send_MSG_SNDIN_VERSION(MSG_SNDIN_VERSION *, struct stream *);
218
int APP_CC get_MSG_SNDIN_VERSION(MSG_SNDIN_VERSION *, struct stream *);
219
int APP_CC send_MSG_SNDIN_FORMATS(MSG_SNDIN_FORMATS *, struct stream *);
220
int APP_CC get_MSG_SNDIN_FORMATS(MSG_SNDIN_FORMATS *, struct stream *);
221
int APP_CC send_MSG_SNDIN_OPEN(MSG_SNDIN_OPEN *, struct stream *);
222
int APP_CC get_MSG_SNDIN_OPEN(MSG_SNDIN_OPEN *, struct stream *);
223
int APP_CC send_WAVEFORMAT_EXTENSIBLE(WAVEFORMAT_EXTENSIBLE *, struct stream *);
224
int APP_CC get_WAVEFORMAT_EXTENSIBLE(WAVEFORMAT_EXTENSIBLE *, struct stream *);
225
int APP_CC send_MSG_SNDIN_OPEN_REPLY(MSG_SNDIN_OPEN_REPLY *, struct stream *);
226
int APP_CC get_MSG_SNDIN_OPEN_REPLY(MSG_SNDIN_OPEN_REPLY *, struct stream *);
227
int APP_CC send_MSG_SNDIN_DATA_INCOMING(MSG_SNDIN_DATA_INCOMING *, struct stream *);
228
int APP_CC get_MSG_SNDIN_DATA_INCOMING(MSG_SNDIN_DATA_INCOMING *, struct stream *);
229
int APP_CC send_MSG_SNDIN_DATA(MSG_SNDIN_DATA *, struct stream *);
230
int APP_CC get_MSG_SNDIN_DATA(MSG_SNDIN_DATA *, struct stream *);
231
int APP_CC send_MSG_SNDIN_FORMATCHANGE(MSG_SNDIN_FORMATCHANGE *, struct stream *);
232
int APP_CC get_MSG_SNDIN_FORMATCHANGE(MSG_SNDIN_FORMATCHANGE *, struct stream *);
233
234
235
/**************************************************************************
236
 *
237
 *	senders (serializers)
238
 */
239
240
int APP_CC send_CAPABILITY_SET(CAPABILITY_SET *, struct stream *);
241
int APP_CC send_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE *, struct stream *);
242
int APP_CC send_DR_CLOSE_REQ(DR_CLOSE_REQ *, struct stream *);
243
int APP_CC send_DR_READ_REQ(DR_READ_REQ *, struct stream *);
244
int APP_CC send_DR_WRITE_REQ(DR_WRITE_REQ *, struct stream *);
245
int APP_CC send_DR_CONTROL_REQ(DR_CONTROL_REQ *, struct stream *);
246
int APP_CC send_DR_CREATE_RSP(DR_CREATE_RSP *, struct stream *);
247
int APP_CC send_DR_CLOSE_RSP(DR_CLOSE_RSP *, struct stream *);
248
int APP_CC send_DR_READ_RSP(DR_READ_RSP *, struct stream *);
249
int APP_CC send_DR_WRITE_RSP(DR_WRITE_RSP *, struct stream *);
250
int APP_CC send_DR_CONTROL_RSP(DR_CONTROL_RSP *, struct stream *);
251
int APP_CC send_RDP_LOCK_INFO(RDP_LOCK_INFO *, struct stream *);
252
int APP_CC send_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP *, struct stream *);
253
int APP_CC send_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP *, struct stream *);
254
int APP_CC send_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ *, struct stream *);
255
int APP_CC send_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM *, struct stream *);
256
int APP_CC send_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ *, struct stream *);
257
int APP_CC send_GENERAL_CAPS_SET(GENERAL_CAPS_SET *, struct stream *);
258
int APP_CC send_PRINTER_CAPS_SET(PRINTER_CAPS_SET *, struct stream *);
259
int APP_CC send_PORT_CAPS_SET(PORT_CAPS_SET *, struct stream *);
260
int APP_CC send_DRIVE_CAPS_SET(DRIVE_CAPS_SET *, struct stream *);
261
int APP_CC send_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET *, struct stream *);
262
int APP_CC send_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ *, struct stream *);
263
int APP_CC send_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE *, struct stream *);
264
int APP_CC send_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE *, struct stream *);
265
int APP_CC send_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST *, struct stream *);
266
int APP_CC send_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ *, struct stream *);
267
int APP_CC send_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ *, struct stream *);
268
int APP_CC send_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ *, struct stream *);
269
int APP_CC send_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ *, struct stream *);
270
int APP_CC send_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ *, struct stream *);
271
int APP_CC send_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ *, struct stream *);
272
int APP_CC send_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ *, struct stream *);
273
int APP_CC send_DR_DRIVE_SET_INFORMATION_REQ_rename(DR_DRIVE_SET_INFORMATION_REQ *, struct stream *);
274
int APP_CC send_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION *, struct stream *);
275
int APP_CC send_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ *, struct stream *);
276
int APP_CC send_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION *, struct stream *);
277
int APP_CC send_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *, struct stream *);
278
int APP_CC send_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP *, struct stream *);
279
int APP_CC send_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *, struct stream *);
280
int APP_CC send_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP *, struct stream *);
281
int APP_CC send_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP *, struct stream *);
282
int APP_CC send_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *, struct stream *);
283
int APP_CC send_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP *, struct stream *);
284
int APP_CC send_FILE_NAME_INFORMATION(FILE_NAME_INFORMATION *, struct stream *);
285
int APP_CC send_FILE_BASIC_INFORMATION(FILE_BASIC_INFORMATION *, struct stream *);
286
int APP_CC send_FILE_STANDARD_INFORMATION(FILE_STANDARD_INFORMATION *, struct stream *);
287
int APP_CC send_FILE_ALL_INFORMATION(FILE_ALL_INFORMATION *, struct stream *);
288
int APP_CC send_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP *, struct stream *);
289
int APP_CC send_DR_DRIVE_SET_INFORMATION_RSP(DR_DRIVE_SET_INFORMATION_RSP *, struct stream *);
290
291
292
293
/**************************************************************************
294
 *
295
 *	destructors
296
 */
297
298
void APP_CC destroy_RDPDR_HEADER(RDPDR_HEADER *);
299
void APP_CC destroy_CAPABILITY_HEADER(CAPABILITY_HEADER *);
300
void APP_CC destroy_CAPABILITY_SET(CAPABILITY_SET *);
301
void APP_CC destroy_DEVICE_ANNOUNCE(DEVICE_ANNOUNCE *);
302
void APP_CC destroy_DR_DEVICE_IOREQUEST(DR_DEVICE_IOREQUEST *);
303
void APP_CC destroy_DR_CREATE_REQ(DR_CREATE_REQ *);
304
void APP_CC destroy_DR_CLOSE_REQ(DR_CLOSE_REQ *);
305
void APP_CC destroy_DR_READ_REQ(DR_READ_REQ *);
306
void APP_CC destroy_DR_WRITE_REQ(DR_WRITE_REQ *);
307
void APP_CC destroy_DR_CONTROL_REQ(DR_CONTROL_REQ *);
308
void APP_CC destroy_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *);
309
void APP_CC destroy_DR_CREATE_RSP(DR_CREATE_RSP *);
310
void APP_CC destroy_DR_CLOSE_RSP(DR_CLOSE_RSP *);
311
void APP_CC destroy_DR_READ_RSP(DR_READ_RSP *);
312
void APP_CC destroy_DR_WRITE_RSP(DR_WRITE_RSP *);
313
void APP_CC destroy_DR_CONTROL_RSP(DR_CONTROL_RSP *);
314
void APP_CC destroy_RDP_LOCK_INFO(RDP_LOCK_INFO *);
315
void APP_CC destroy_DR_CORE_DEVICE_ANNOUNCE_RSP(DR_CORE_DEVICE_ANNOUNCE_RSP *);
316
void APP_CC destroy_DR_CORE_SERVER_ANNOUNCE_REQ(DR_CORE_SERVER_ANNOUNCE_REQ *);
317
void APP_CC destroy_DR_CORE_SERVER_ANNOUNCE_RSP(DR_CORE_SERVER_ANNOUNCE_RSP *);
318
void APP_CC destroy_DR_CORE_CLIENT_NAME_REQ(DR_CORE_CLIENT_NAME_REQ *);
319
void APP_CC destroy_DR_CORE_SERVER_CLIENTID_CONFIRM(DR_CORE_SERVER_CLIENTID_CONFIRM *);
320
void APP_CC destroy_DR_CORE_CAPABILITY_REQ(DR_CORE_CAPABILITY_REQ *);
321
void APP_CC destroy_GENERAL_CAPS_SET(GENERAL_CAPS_SET *);
322
void APP_CC destroy_PRINTER_CAPS_SET(PRINTER_CAPS_SET *);
323
void APP_CC destroy_PORT_CAPS_SET(PORT_CAPS_SET *);
324
void APP_CC destroy_DRIVE_CAPS_SET(DRIVE_CAPS_SET *);
325
void APP_CC destroy_SMARTCARD_CAPS_SET(SMARTCARD_CAPS_SET *);
326
void APP_CC destroy_DR_CORE_DEVICELIST_ANNOUNCE_REQ(DR_CORE_DEVICELIST_ANNOUNCE_REQ *);
327
void APP_CC destroy_DR_DEVICELIST_ANNOUNCE(DR_DEVICELIST_ANNOUNCE *);
328
void APP_CC destroy_DR_DEVICELIST_REMOVE(DR_DEVICELIST_REMOVE *);
329
void APP_CC destroy_DR_DRIVE_CORE_DEVICE_IOREQUEST(DR_DRIVE_CORE_DEVICE_IOREQUEST *);
330
void APP_CC destroy_DR_DRIVE_CREATE_REQ(DR_DRIVE_CREATE_REQ *);
331
void APP_CC destroy_DR_DRIVE_CLOSE_REQ(DR_DRIVE_CLOSE_REQ *);
332
void APP_CC destroy_DR_DRIVE_READ_REQ(DR_DRIVE_READ_REQ *);
333
void APP_CC destroy_DR_DRIVE_WRITE_REQ(DR_DRIVE_WRITE_REQ *);
334
void APP_CC destroy_DR_DRIVE_CONTROL_REQ(DR_DRIVE_CONTROL_REQ *);
335
void APP_CC destroy_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ *);
336
void APP_CC destroy_DR_DRIVE_SET_VOLUME_INFORMATION_REQ(DR_DRIVE_SET_VOLUME_INFORMATION_REQ *);
337
void APP_CC destroy_DR_DRIVE_QUERY_INFORMATION_REQ(DR_DRIVE_QUERY_INFORMATION_REQ *);
338
void APP_CC destroy_DR_DRIVE_SET_INFORMATION_REQ(DR_DRIVE_SET_INFORMATION_REQ *);
339
void APP_CC destroy_RDP_FILE_RENAME_INFORMATION(RDP_FILE_RENAME_INFORMATION *);
340
void APP_CC destroy_DR_DRIVE_QUERY_DIRECTORY_REQ(DR_DRIVE_QUERY_DIRECTORY_REQ *);
341
void APP_CC destroy_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_REQ *);
342
void APP_CC destroy_DR_DRIVE_LOCK_REQ(DR_DRIVE_LOCK_REQ *);
343
void APP_CC destroy_DR_DRIVE_CORE_DEVICE_IOCOMPLETION(DR_DRIVE_CORE_DEVICE_IOCOMPLETION *);
344
void APP_CC destroy_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *);
345
void APP_CC destroy_DR_DRIVE_CLOSE_RSP(DR_DRIVE_CLOSE_RSP *);
346
void APP_CC destroy_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *);
347
void APP_CC destroy_DR_DRIVE_SET_VOLUME_INFORMATION_RSP(DR_DRIVE_SET_VOLUME_INFORMATION_RSP *);
348
void APP_CC destroy_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP *);
349
void APP_CC destroy_DR_DRIVE_QUERY_DIRECTORY_RSP(DR_DRIVE_QUERY_DIRECTORY_RSP *);
350
void APP_CC destroy_DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP(DR_DRIVE_NOTIFY_CHANGE_DIRECTORY_RSP *);
351
void APP_CC destroy_DR_DRIVE_LOCK_RSP(DR_DRIVE_LOCK_RSP *);
352
void APP_CC destroy_DR_CORE_USER_LOGGEDON(DR_CORE_USER_LOGGEDON *);
353
void APP_CC destroy_DYNVC_CAPS_VERSION1(DYNVC_CAPS_VERSION1 *);
354
void APP_CC destroy_DYNVC_CAPS_VERSION2(DYNVC_CAPS_VERSION2 *);
355
void APP_CC destroy_DYNVC_CAPS_RSP(DYNVC_CAPS_RSP *);
356
void APP_CC destroy_DYNVC_CREATE_REQ(DYNVC_CREATE_REQ *);
357
void APP_CC destroy_DYNVC_CREATE_RSP(DYNVC_CREATE_RSP *);
358
void APP_CC destroy_DYNVC_DATA_FIRST(DYNVC_DATA_FIRST *);
359
void APP_CC destroy_DYNVC_DATA(DYNVC_DATA *);
360
void APP_CC destroy_DYNVC_CLOSE(DYNVC_CLOSE *);
361
362
363
364
/**************************************************************************
365
 *
366
 *	instantiators
367
 */
368
369
void * APP_CC rdpdr_inst(const char *);
370
371
372
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/rdpeai_defs.h (+13 lines)
Line 0    Link Here 
1
#if !defined(XRDP_RDPEAI_DEFS)
2
#define	XRDP_RDPEAI_DEFS
3
4
5
typedef struct _SNDIN_PDU {
6
	uint8_t				MessageId;
7
} SNDIN_PDU;
8
9
typedef struct _MSG_SNDIN_VERSION {
10
} MSG_SNDIN_VERSION;
11
12
13
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/recording_defs.h (+129 lines)
Line 0    Link Here 
1
#if !defined(__XRDP_SNDIN__)
2
#define __XRDP_SNDIN__
3
4
5
#include <stdint.h>
6
#include "devredir_defs.h"
7
#include "sound_defs.h"
8
9
10
/*****************************************************************************/
11
12
enum {
13
	CMSG_SNDIN_VERSION		= 0x01,
14
#define	CMSG_SNDIN_VERSION		  CMSG_SNDIN_VERSION
15
	CMSG_SNDIN_FORMATS		= 0x02,
16
#define	CMSG_SNDIN_FORMATS		  CMSG_SNDIN_FORMATS
17
	CMSG_SNDIN_OPEN			= 0x03,
18
#define	CMSG_SNDIN_OPEN			  CMSG_SNDIN_OPEN
19
	CMSG_SNDIN_OPEN_REPLY		= 0x04,
20
#define	CMSG_SNDIN_OPEN_REPLY		  CMSG_SNDIN_OPEN_REPLY
21
	CMSG_SNDIN_DATA_INCOMING	= 0x05,
22
#define	CMSG_SNDIN_DATA_INCOMING	  CMSG_SNDIN_DATA_INCOMING
23
	CMSG_SNDIN_DATA			= 0x06,
24
#define	CMSG_SNDIN_DATA			  CMSG_SNDIN_DATA
25
	CMSG_SNDIN_FORMATCHANGE		= 0x07
26
#define	CMSG_SNDIN_FORMATCHANGE		  CMSG_SNDIN_FORMATCHANGE
27
};
28
29
#define	SNDIN_VERSION			0x00000001
30
31
typedef struct _AUDIO_FORMAT_REC {
32
    WORD		wFormatTag;
33
    WORD		nChannels;
34
    DWORD		nSamplesPerSec;
35
    DWORD		nAvgBytesPerSec;
36
    WORD		nBlockAlign;
37
    WORD		wBitsPerSample;
38
    WORD		cbSize;			/* cbSize = the number of bytes contained by data[] */
39
    BYTE		data[0];
40
} AUDIO_FORMAT_REC, WAVEFORMATEX_REC;
41
42
typedef struct _SNDIN_PDU {
43
	uint8_t			MessageId;
44
} SNDIN_PDU;
45
46
typedef struct _MSG_SNDIN_VERSION {
47
	SNDIN_PDU		Header;
48
	DWORD			Version;
49
} MSG_SNDIN_VERSION;
50
51
typedef struct _MSG_SNDIN_FORMATS {
52
	SNDIN_PDU		Header;
53
	DWORD			NumFormats;
54
	DWORD			cbSizeFormatsPacket;
55
	AUDIO_FORMAT_REC	SoundFormats[0];
56
/*	BYTE			ExtraData[0];		*/
57
} MSG_SNDIN_FORMATS;
58
59
typedef struct _MSG_SNDIN_OPEN {
60
	SNDIN_PDU		Header;
61
	DWORD			FramesPerPacket;
62
	DWORD			initialFormat;
63
	WORD			wFormatTag;
64
	WORD			nChannels;
65
	DWORD			nSamplesPerSec;
66
	DWORD			nAvgBytesPerSec;
67
	WORD			nBlockAlign;
68
	WORD			wBitsPerSample;
69
	WORD			cbSize;
70
	BYTE			ExtraFormatData[0];
71
				/* 
72
				 * if wFormatTag == WAVE_FORMAT_EXTENSIBLE,
73
				 * then ExtraFormatData must be a structure
74
				 * of type WAVEFORMAT_EXTENSIBLE.
75
				 */
76
} MSG_SNDIN_OPEN;
77
78
#define	WAVE_FORMAT_EXTENSIBLE			0xFFFE
79
80
typedef struct _WAVEFORMAT_EXTENSIBLE {
81
	WORD			wValidBitsPerSample;
82
	DWORD			dwChannelMask;
83
	GUID			SubFormat;	/* this field MUST be set to KSDATAFORMAT_SUBTYPE_PCM ({00000001-0000-0010-8000-00aa00389b71})	*/
84
	#define	KSDATAFORMAT_SUBTYPE_PCM	{ 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }
85
	/* #define	KSDATAFORMAT_SUBTYPE_PCM	00000001-0000-0010-8000-00aa00389b71 */
86
	#define SPEAKER_FRONT_LEFT		0x00000001
87
	#define SPEAKER_FRONT_RIGHT		0x00000002
88
	#define SPEAKER_FRONT_CENTER		0x00000004
89
	#define SPEAKER_LOW_FREQUENCY		0x00000008
90
	#define SPEAKER_BACK_LEFT		0x00000010
91
	#define SPEAKER_BACK_RIGHT		0x00000020
92
	#define SPEAKER_FRONT_LEFT_OF_CENTER	0x00000040
93
	#define SPEAKER_FRONT_RIGHT_OF_CENTER	0x00000080
94
	#define SPEAKER_BACK_CENTER		0x00000100
95
	#define SPEAKER_SIDE_LEFT		0x00000200
96
	#define SPEAKER_SIDE_RIGHT		0x00000400
97
	#define SPEAKER_TOP_CENTER		0x00000800
98
	#define SPEAKER_TOP_FRONT_LEFT		0x00001000
99
	#define SPEAKER_TOP_FRONT_CENTER	0x00002000
100
	#define SPEAKER_TOP_FRONT_RIGHT		0x00004000
101
	#define SPEAKER_TOP_BACK_LEFT		0x00008000
102
	#define SPEAKER_TOP_BACK_CENTER		0x00010000
103
	#define SPEAKER_TOP_BACK_RIGHT		0x00020000
104
} WAVEFORMAT_EXTENSIBLE;
105
106
typedef DWORD	HRESULT;
107
108
typedef struct _MSG_SNDIN_OPEN_REPLY {
109
	SNDIN_PDU				Header;
110
	HRESULT					Result;
111
} MSG_SNDIN_OPEN_REPLY;
112
113
typedef struct _MSG_SNDIN_DATA_INCOMING {
114
	SNDIN_PDU				Header;
115
} MSG_SNDIN_DATA_INCOMING;
116
117
typedef struct _MSG_SNDIN_DATA {
118
	SNDIN_PDU				Header;
119
	size_t					len;
120
	BYTE					Data[0];
121
} MSG_SNDIN_DATA;
122
123
typedef struct _MSG_SNDIN_FORMATCHANGE {
124
	SNDIN_PDU				Header;
125
	DWORD					NewFormat;
126
} MSG_SNDIN_FORMATCHANGE;
127
128
129
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/ringbuffer.c (+309 lines)
Line 0    Link Here 
1
/*
2
  Copyright (C) 2000 Paul Davis
3
  Copyright (C) 2003 Rohan Drape
4
    
5
  This program is free software; you can redistribute it and/or modify
6
  it under the terms of the GNU Lesser General Public License as published by
7
  the Free Software Foundation; either version 2.1 of the License, or
8
  (at your option) any later version.
9
    
10
  This program is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
  GNU Lesser General Public License for more details.
14
    
15
  You should have received a copy of the GNU Lesser General Public License
16
  along with this program; if not, write to the Free Software 
17
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19
  Adapted (i.e., copied verbatim) from JACK Audio's ringbuffer.c
20
    
21
  ISO/POSIX C version of Paul Davis's lock free ringbuffer C++ code.
22
  This is safe for the case of one read thread and one write thread.
23
*/
24
25
#include <stdlib.h>
26
#include <string.h>
27
#include <sys/mman.h>
28
#include "ringbuffer.h"
29
30
/* Create a new ringbuffer to hold at least `sz' bytes of data. The
31
   actual buffer size is rounded up to the next power of two.  */
32
33
xrdp_ringbuffer_t *
34
xrdp_ringbuffer_create (size_t sz)
35
{
36
  int power_of_two;
37
  xrdp_ringbuffer_t *rb;
38
39
  rb = malloc (sizeof (xrdp_ringbuffer_t));
40
41
  for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++);
42
43
  rb->size = 1 << power_of_two;
44
  rb->size_mask = rb->size;
45
  rb->size_mask -= 1;
46
  rb->write_ptr = 0;
47
  rb->read_ptr = 0;
48
  rb->buf = malloc (rb->size);
49
  rb->mlocked = 0;
50
51
  return rb;
52
}
53
54
/* Free all data associated with the ringbuffer `rb'. */
55
56
void
57
xrdp_ringbuffer_free (xrdp_ringbuffer_t * rb)
58
{
59
  if (rb->mlocked) {
60
    munlock (rb->buf, rb->size);
61
  }
62
  free (rb->buf);
63
}
64
65
/* Lock the data block of `rb' using the system call 'mlock'.  */
66
67
int
68
xrdp_ringbuffer_mlock (xrdp_ringbuffer_t * rb)
69
{
70
  if (mlock (rb->buf, rb->size)) {
71
    return -1;
72
  }
73
  rb->mlocked = 1;
74
  return 0;
75
}
76
77
/* Reset the read and write pointers to zero. This is not thread
78
   safe. */
79
80
void
81
xrdp_ringbuffer_reset (xrdp_ringbuffer_t * rb)
82
{
83
  rb->read_ptr = 0;
84
  rb->write_ptr = 0;
85
}
86
87
/* Return the number of bytes available for reading.  This is the
88
   number of bytes in front of the read pointer and behind the write
89
   pointer.  */
90
91
size_t
92
xrdp_ringbuffer_read_space (xrdp_ringbuffer_t * rb)
93
{
94
  size_t w, r;
95
96
  w = rb->write_ptr;
97
  r = rb->read_ptr;
98
99
  if (w > r) {
100
    return w - r;
101
  } else {
102
    return (w - r + rb->size) & rb->size_mask;
103
  }
104
}
105
106
/* Return the number of bytes available for writing.  This is the
107
   number of bytes in front of the write pointer and behind the read
108
   pointer.  */
109
110
size_t
111
xrdp_ringbuffer_write_space (xrdp_ringbuffer_t * rb)
112
{
113
  size_t w, r;
114
115
  w = rb->write_ptr;
116
  r = rb->read_ptr;
117
118
  if (w > r) {
119
    return ((r - w + rb->size) & rb->size_mask) - 1;
120
  } else if (w < r) {
121
    return (r - w) - 1;
122
  } else {
123
    return rb->size - 1;
124
  }
125
}
126
127
/* The copying data reader.  Copy at most `cnt' bytes from `rb' to
128
   `dest'.  Returns the actual number of bytes copied. */
129
130
size_t
131
xrdp_ringbuffer_read (xrdp_ringbuffer_t * rb, char *dest, size_t cnt)
132
{
133
  size_t free_cnt;
134
  size_t cnt2;
135
  size_t to_read;
136
  size_t n1, n2;
137
138
  if ((free_cnt = xrdp_ringbuffer_read_space (rb)) == 0) {
139
    return 0;
140
  }
141
142
  to_read = cnt > free_cnt ? free_cnt : cnt;
143
144
  cnt2 = rb->read_ptr + to_read;
145
146
  if (cnt2 > rb->size) {
147
    n1 = rb->size - rb->read_ptr;
148
    n2 = cnt2 & rb->size_mask;
149
  } else {
150
    n1 = to_read;
151
    n2 = 0;
152
  }
153
154
  memcpy (dest, &(rb->buf[rb->read_ptr]), n1);
155
  rb->read_ptr += n1;
156
  rb->read_ptr &= rb->size_mask;
157
158
  if (n2) {
159
    memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2);
160
    rb->read_ptr += n2;
161
    rb->read_ptr &= rb->size_mask;
162
  }
163
164
  return to_read;
165
}
166
167
/* The copying data writer.  Copy at most `cnt' bytes to `rb' from
168
   `src'.  Returns the actual number of bytes copied. */
169
170
size_t
171
xrdp_ringbuffer_write (xrdp_ringbuffer_t * rb, char *src, size_t cnt)
172
{
173
  size_t free_cnt;
174
  size_t cnt2;
175
  size_t to_write;
176
  size_t n1, n2;
177
178
  if ((free_cnt = xrdp_ringbuffer_write_space (rb)) == 0) {
179
    return 0;
180
  }
181
182
  to_write = cnt > free_cnt ? free_cnt : cnt;
183
184
  cnt2 = rb->write_ptr + to_write;
185
186
  if (cnt2 > rb->size) {
187
    n1 = rb->size - rb->write_ptr;
188
    n2 = cnt2 & rb->size_mask;
189
  } else {
190
    n1 = to_write;
191
    n2 = 0;
192
  }
193
194
  memcpy (&(rb->buf[rb->write_ptr]), src, n1);
195
  rb->write_ptr += n1;
196
  rb->write_ptr &= rb->size_mask;
197
198
  if (n2) {
199
    memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2);
200
    rb->write_ptr += n2;
201
    rb->write_ptr &= rb->size_mask;
202
  }
203
204
  return to_write;
205
}
206
207
/* Advance the read pointer `cnt' places. */
208
209
void
210
xrdp_ringbuffer_read_advance (xrdp_ringbuffer_t * rb, size_t cnt)
211
{
212
  rb->read_ptr += cnt;
213
  rb->read_ptr &= rb->size_mask;
214
}
215
216
/* Advance the write pointer `cnt' places. */
217
218
void
219
xrdp_ringbuffer_write_advance (xrdp_ringbuffer_t * rb, size_t cnt)
220
{
221
  rb->write_ptr += cnt;
222
  rb->write_ptr &= rb->size_mask;
223
}
224
225
/* The non-copying data reader.  `vec' is an array of two places.  Set
226
   the values at `vec' to hold the current readable data at `rb'.  If
227
   the readable data is in one segment the second segment has zero
228
   length.  */
229
230
void
231
xrdp_ringbuffer_get_read_vector (xrdp_ringbuffer_t * rb,
232
                            xrdp_ringbuffer_data_t * vec)
233
{
234
  size_t free_cnt;
235
  size_t cnt2;
236
  size_t w, r;
237
238
  w = rb->write_ptr;
239
  r = rb->read_ptr;
240
241
  if (w > r) {
242
    free_cnt = w - r;
243
  } else {
244
    free_cnt = (w - r + rb->size) & rb->size_mask;
245
  }
246
247
  cnt2 = r + free_cnt;
248
249
  if (cnt2 > rb->size) {
250
251
    /* Two part vector: the rest of the buffer after the current write
252
       ptr, plus some from the start of the buffer. */
253
254
    vec[0].buf = &(rb->buf[r]);
255
    vec[0].len = rb->size - r;
256
    vec[1].buf = rb->buf;
257
    vec[1].len = cnt2 & rb->size_mask;
258
259
  } else {
260
261
    /* Single part vector: just the rest of the buffer */
262
263
    vec[0].buf = &(rb->buf[r]);
264
    vec[0].len = free_cnt;
265
    vec[1].len = 0;
266
  }
267
}
268
269
/* The non-copying data writer.  `vec' is an array of two places.  Set
270
   the values at `vec' to hold the current writeable data at `rb'.  If
271
   the writeable data is in one segment the second segment has zero
272
   length.  */
273
274
void
275
xrdp_ringbuffer_get_write_vector (xrdp_ringbuffer_t * rb,
276
                                  xrdp_ringbuffer_data_t * vec)
277
{
278
  size_t free_cnt;
279
  size_t cnt2;
280
  size_t w, r;
281
282
  w = rb->write_ptr;
283
  r = rb->read_ptr;
284
285
  if (w > r) {
286
    free_cnt = ((r - w + rb->size) & rb->size_mask) - 1;
287
  } else if (w < r) {
288
    free_cnt = (r - w) - 1;
289
  } else {
290
    free_cnt = rb->size - 1;
291
  }
292
293
  cnt2 = w + free_cnt;
294
295
  if (cnt2 > rb->size) {
296
297
    /* Two part vector: the rest of the buffer after the current write
298
       ptr, plus some from the start of the buffer. */
299
300
    vec[0].buf = &(rb->buf[w]);
301
    vec[0].len = rb->size - w;
302
    vec[1].buf = rb->buf;
303
    vec[1].len = cnt2 & rb->size_mask;
304
  } else {
305
    vec[0].buf = &(rb->buf[w]);
306
    vec[0].len = free_cnt;
307
    vec[1].len = 0;
308
  }
309
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/ringbuffer.h (+218 lines)
Line 0    Link Here 
1
/*
2
    Copyright (C) 2000 Paul Davis
3
    Copyright (C) 2003 Rohan Drape
4
    
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU Lesser General Public License as published by
7
    the Free Software Foundation; either version 2.1 of the License, or
8
    (at your option) any later version.
9
    
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU Lesser General Public License for more details.
14
    
15
    You should have received a copy of the GNU Lesser General Public License
16
    along with this program; if not, write to the Free Software 
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19
    $Id: ringbuffer.h,v 1.4 2003/12/21 02:40:46 joq Exp $
20
*/
21
22
#ifndef _XRDP_RINGBUFFER_H
23
#define _XRDP_RINGBUFFER_H
24
25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28
29
#include <sys/types.h>
30
31
/** @file ringbuffer.h
32
 *
33
 * A set of library functions to make lock-free ringbuffers available
34
 * to JACK clients.  The `capture_client.c' (in the example_clients
35
 * directory) is a fully functioning user of this API.
36
 *
37
 * The key attribute of a ringbuffer is that it can be safely accessed
38
 * by two threads simultaneously -- one reading from the buffer and
39
 * the other writing to it -- without using any synchronization or
40
 * mutual exclusion primitives.  For this to work correctly, there can
41
 * only be a single reader and a single writer thread.  Their
42
 * identities cannot be interchanged.
43
 */
44
45
typedef struct  
46
{
47
  char  *buf;
48
  size_t len;
49
} 
50
xrdp_ringbuffer_data_t ;
51
52
typedef struct
53
{
54
  char           *buf;
55
  volatile size_t write_ptr;
56
  volatile size_t read_ptr;
57
  size_t          size;
58
  size_t          size_mask;
59
  int             mlocked;
60
} 
61
xrdp_ringbuffer_t ;
62
63
/**
64
 * Allocates a ringbuffer data structure of a specified size. The
65
 * caller must arrange for a call to xrdp_ringbuffer_free() to release
66
 * the memory associated with the ringbuffer.
67
 *
68
 * @param sz the ringbuffer size in bytes.
69
 *
70
 * @return a pointer to a new xrdp_ringbuffer_t, if successful; NULL
71
 * otherwise.
72
 */
73
xrdp_ringbuffer_t *xrdp_ringbuffer_create(size_t sz);
74
75
/**
76
 * Frees the ringbuffer data structure allocated by an earlier call to
77
 * xrdp_ringbuffer_create().
78
 *
79
 * @param rb a pointer to the ringbuffer structure.
80
 */
81
void xrdp_ringbuffer_free(xrdp_ringbuffer_t *rb);
82
83
/**
84
 * Fill a data structure with a description of the current readable
85
 * data held in the ringbuffer.  This description is returned in a two
86
 * element array of xrdp_ringbuffer_data_t.  Two elements are needed
87
 * because the data to be read may be split across the end of the
88
 * ringbuffer.
89
 *
90
 * The first element will always contain a valid @a len field, which
91
 * may be zero or greater.  If the @a len field is non-zero, then data
92
 * can be read in a contiguous fashion using the address given in the
93
 * corresponding @a buf field.
94
 *
95
 * If the second element has a non-zero @a len field, then a second
96
 * contiguous stretch of data can be read from the address given in
97
 * its corresponding @a buf field.
98
 *
99
 * @param rb a pointer to the ringbuffer structure.
100
 * @param vec a pointer to a 2 element array of xrdp_ringbuffer_data_t.
101
 *
102
 */
103
void xrdp_ringbuffer_get_read_vector(xrdp_ringbuffer_t *rb,
104
                                     xrdp_ringbuffer_data_t *vec);
105
106
/**
107
 * Fill a data structure with a description of the current writable
108
 * space in the ringbuffer.  The description is returned in a two
109
 * element array of xrdp_ringbuffer_data_t.  Two elements are needed
110
 * because the space available for writing may be split across the end
111
 * of the ringbuffer.
112
 *
113
 * The first element will always contain a valid @a len field, which
114
 * may be zero or greater.  If the @a len field is non-zero, then data
115
 * can be written in a contiguous fashion using the address given in
116
 * the corresponding @a buf field.
117
 *
118
 * If the second element has a non-zero @a len field, then a second
119
 * contiguous stretch of data can be written to the address given in
120
 * the corresponding @a buf field.
121
 *
122
 * @param rb a pointer to the ringbuffer structure.
123
 * @param vec a pointer to a 2 element array of xrdp_ringbuffer_data_t.
124
 */
125
void xrdp_ringbuffer_get_write_vector(xrdp_ringbuffer_t *rb,
126
                                      xrdp_ringbuffer_data_t *vec);
127
128
/**
129
 * Read data from the ringbuffer.
130
 *
131
 * @param rb a pointer to the ringbuffer structure.
132
 * @param dest a pointer to a buffer where data read from the
133
 * ringbuffer will go.
134
 * @param cnt the number of bytes to read.
135
 *
136
 * @return the number of bytes read, which may range from 0 to cnt.
137
 */
138
size_t xrdp_ringbuffer_read(xrdp_ringbuffer_t *rb, char *dest, size_t cnt);
139
140
/**
141
 * Advance the read pointer.
142
 *
143
 * After data have been read from the ringbuffer using the pointers
144
 * returned by xrdp_ringbuffer_get_read_vector(), use this function to
145
 * advance the buffer pointers, making that space available for future
146
 * write operations.
147
 *
148
 * @param rb a pointer to the ringbuffer structure.
149
 * @param cnt the number of bytes read.
150
 */
151
void xrdp_ringbuffer_read_advance(xrdp_ringbuffer_t *rb, size_t cnt);
152
153
/**
154
 * Return the number of bytes available for reading.
155
 *
156
 * @param rb a pointer to the ringbuffer structure.
157
 *
158
 * @return the number of bytes available to read.
159
 */
160
size_t xrdp_ringbuffer_read_space(xrdp_ringbuffer_t *rb);
161
162
/**
163
 * Lock a ringbuffer data block into memory.
164
 *
165
 * Uses the mlock() system call.  This is not a realtime operation.
166
 *
167
 * @param rb a pointer to the ringbuffer structure.
168
 */
169
int xrdp_ringbuffer_mlock(xrdp_ringbuffer_t *rb);
170
171
/**
172
 * Reset the read and write pointers, making an empty buffer.
173
 *
174
 * This is not thread safe.
175
 *
176
 * @param rb a pointer to the ringbuffer structure.
177
 */
178
void xrdp_ringbuffer_reset(xrdp_ringbuffer_t *rb);
179
180
/**
181
 * Write data into the ringbuffer.
182
 *
183
 * @param rb a pointer to the ringbuffer structure.
184
 * @param src a pointer to the data to be written to the ringbuffer.
185
 * @param cnt the number of bytes to write.
186
 *
187
 * @return the number of bytes write, which may range from 0 to cnt
188
 */
189
size_t xrdp_ringbuffer_write(xrdp_ringbuffer_t *rb, char *src, size_t cnt);
190
191
/**
192
 * Advance the write pointer.
193
 *
194
 * After data have been written the ringbuffer using the pointers
195
 * returned by xrdp_ringbuffer_get_write_vector(), use this function
196
 * to advance the buffer pointer, making the data available for future
197
 * read operations.
198
 *
199
 * @param rb a pointer to the ringbuffer structure.
200
 * @param cnt the number of bytes written.
201
 */
202
void xrdp_ringbuffer_write_advance(xrdp_ringbuffer_t *rb, size_t cnt);
203
204
/**
205
 * Return the number of bytes available for writing.
206
 *
207
 * @param rb a pointer to the ringbuffer structure.
208
 *
209
 * @return the amount of free space (in bytes) available for writing.
210
 */
211
size_t xrdp_ringbuffer_write_space(xrdp_ringbuffer_t *rb);
212
213
214
#ifdef __cplusplus
215
}
216
#endif
217
218
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/sound_defs.h (+214 lines)
Line 0    Link Here 
1
#ifndef _RDPSND_DEFS_
2
#define _RDPSND_DEFS_
3
4
#include <stdint.h>
5
#include <sys/timeb.h>
6
7
/* MS PDU definitions */
8
#define SNDC_CLOSE			0x01
9
#define SNDC_WAVE			0x02
10
#define SNDC_SETVOLUME			0x03
11
#define SNDC_SETPITCH			0x04
12
#define SNDC_WAVECONFIRM		0x05
13
#define SNDC_TRAINING			0x06
14
#define SNDC_FORMATS			0x07
15
#define SNDC_CRYPTKEY			0x08
16
#define SNDC_WAVEENCRYPT		0x09
17
#define SNDC_UDPWAVE			0x0A
18
#define SNDC_UDPWAVELAST		0x0B
19
#define SNDC_QUALITYMODE		0x0C
20
21
/* MS Wave Format definitions */
22
#define WAVE_FORMAT_UNKNOWN		0x0000
23
#define WAVE_FORMAT_PCM			0x0001
24
#define WAVE_FORMAT_ADPCM		0x0002
25
#define WAVE_FORMAT_ALAW		0x0006
26
#define WAVE_FORMAT_MULAW		0x0007
27
#define WAVE_FORMAT_ULAW		0x0007
28
#define WAVE_FORMAT_IMA_ADPCM		0x0011
29
#define WAVE_FORMAT_DSPGROUP_TRUESPEECH	0x0022
30
#define WAVE_FORMAT_GSM610		0x0031
31
#define WAVE_FORMAT_MSG723		0x0042
32
#define WAVE_FORMAT_MPEGLAYER3		0x0055
33
#define WAVE_FORMAT_VOXWARE_AC8		0x0070
34
#define WAVE_FORMAT_VOXWARE_AC10	0x0071
35
#define WAVE_FORMAT_VOXWARE_AC16	0x0072
36
#define WAVE_FORMAT_VOXWARE_AC20	0x0073
37
/*
38
	Windows XP (0x02):
39
*/
40
#define XRDP_DEFAULT_WAVE_FORMAT	0x0001
41
#define ADPCM_WFX_EXTRA_BYTES		0x0020		/* = 32 */
42
#define MPEGLAYER3_WFX_EXTRA_BYTES	0x000C		/* = 12 */
43
#define MPEGLAYER3_FLAG_PADDING_ON	0x00000001
44
#define MPEGLAYER3_FLAG_PADDING_OFF	0x00000002
45
#define MPEGLAYER3_ID_MPEG		0x00000001
46
#define MPEGLAYER3_NBLOCKSIZE		313
47
#define MPEGLAYER3_NFRAMESPERBLOCK	1
48
#define MPEGLAYER3_NCODECDELAY		1393
49
50
#define TSSNDCAPS_ALIVE			0x00000001
51
#define TSSNDCAPS_VOLUME		0x00000002
52
#define TSSNDCAPS_PITCH			0x00000004
53
54
typedef uint8_t BYTE;
55
typedef uint16_t WORD;
56
typedef uint32_t DWORD;
57
typedef uint64_t QWORD;
58
59
void * APP_CC sound_inst(const char *);
60
61
#ifndef _SNDPROLOG_
62
#define _SNDPROLOG_
63
typedef struct _SNDPROLOG {
64
    BYTE	msgType;
65
    BYTE	bPad;
66
    WORD	BodySize;
67
} SNDPROLOG;
68
#endif
69
70
typedef struct _SNDCLOSE {
71
    SNDPROLOG	Header;
72
    void	(*__constructor)();
73
    void	(*__destructor)(void *);
74
} SNDCLOSE;
75
76
#ifndef _AUDIO_FORMAT_
77
#define _AUDIO_FORMAT_
78
typedef struct _AUDIO_FORMAT {
79
    WORD		wFormatTag;
80
    WORD		nChannels;
81
    DWORD		nSamplesPerSec;
82
    DWORD		nAvgBytesPerSec;
83
    WORD		nBlockAlign;
84
    WORD		wBitsPerSample;
85
    WORD		cbSize;			/* cbSize = the number of bytes contained by data[] */
86
    void		(*__constructor)();
87
    void		(*__destructor)(void *);
88
    BYTE 		data[0];		/* data[cbSize] */
89
} AUDIO_FORMAT, WAVEFORMATEX;
90
#endif
91
92
#ifndef _MP3MWF_
93
#define _MP3MWF_
94
typedef struct _MPEGLAYER3WAVEFORMAT {
95
  /* WAVEFORMATEX	wfx;		*/
96
   WORD		wID;
97
  DWORD		fdwFlags;
98
  WORD		nBlockSize;
99
  WORD		nFramesPerBlock;
100
  WORD		nCodecDelay;
101
} MPEGLAYER3WAVEFORMAT;
102
#endif
103
104
#ifndef GUID_TYPE
105
#define GUID_TYPE
106
typedef struct _GUID {
107
    DWORD	/* unsigned long */		f1;
108
    WORD	/* unsigned short */		f2;
109
    WORD	/* unsigned short */		f3;
110
    BYTE	/* unsigned char */		f4[8];
111
} GUID;
112
#endif /* GUID_TYPE */
113
114
#ifndef _WAVEFORMATEXTENSIBLE_
115
#define _WAVEFORMATEXTENSIBLE_
116
typedef struct _WAVEFORMATEXTENSIBLE {
117
    WAVEFORMATEX    Format;
118
    union {
119
        WORD wValidBitsPerSample;       /* bits of precision  */
120
        WORD wSamplesPerBlock;          /* valid if wBitsPerSample==0 */
121
        WORD wReserved;                 /* If neither applies, set to zero. */
122
    } Samples;
123
    DWORD	    dwChannelMask;      /* which channels are */
124
					/* present in stream  */
125
    GUID	    SubFormat;
126
} WAVEFORMATEXTENSIBLE;
127
#endif /* _WAVEFORMATEXTENSIBLE_ */
128
129
typedef struct _SNDWAV {
130
    DWORD			bPad;
131
    BYTE			*Data;
132
    void			(*__constructor)();
133
    void			(*__destructor)(void *);
134
} SNDWAV;
135
136
typedef struct _SNDWAVINFO {
137
    SNDPROLOG			Header;
138
    WORD			wTimeStamp;
139
    WORD			wFormatNo;
140
    BYTE			cBlockNo;
141
    BYTE			bPad[3];
142
    DWORD			Data;
143
    unsigned int		alen;
144
    SNDWAV			*appendix;
145
    void			(*__constructor)();
146
    void			(*__destructor)(void *);
147
} SNDWAVINFO;
148
149
typedef struct _SNDWAV_CONFIRM {
150
    SNDPROLOG			Header;
151
    WORD			wTimeStamp;
152
    BYTE			cConfirmedBlockNo;
153
    BYTE			bPad;
154
    void			(*__constructor)();
155
    void			(*__destructor)(void *);
156
} SNDWAV_CONFIRM;
157
158
typedef struct _SNDTRAINING {
159
    SNDPROLOG			Header;
160
    WORD			wTimeStamp;
161
    WORD			wPackSize;
162
    BYTE			*data;
163
    void			(*__constructor)();
164
    void			(*__destructor)(void *);
165
} SNDTRAINING;
166
167
typedef struct _SNDTRAININGCONFIRM {
168
    SNDPROLOG			Header;
169
    WORD			wTimeStamp;
170
    WORD			wPackSize;
171
    void			(*__constructor)();
172
    void			(*__destructor)(void *);
173
} SNDTRAININGCONFIRM;
174
175
typedef struct _AUDIO_VERSION_AND_FORMATS {
176
    SNDPROLOG			Header;
177
    DWORD			dwFlags;
178
    DWORD			dwVolume;
179
    DWORD			dwPitch;
180
    WORD			wDGramPort;
181
    WORD			wNumberOfFormats;
182
    BYTE			cLastBlockConfirmed;
183
    WORD			wVersion;
184
    BYTE			bPad;
185
    void			(*__constructor)();
186
    void			(*__destructor)(void *);
187
    tc_t			lock;
188
    AUDIO_FORMAT **		sndFormats;
189
} CLIENT_AUDIO_VERSION_AND_FORMATS, SERVER_AUDIO_VERSION_AND_FORMATS;
190
191
typedef struct _QUALITY_MODE {
192
    SNDPROLOG			Header;
193
    WORD			wQualityMode;
194
    WORD			Reserved;
195
    void			(*__constructor)();
196
    void			(*__destructor)(void *);
197
} QUALITY_MODE;
198
199
200
#if !defined(SOUND_NEW)
201
#define SOUND_NEW(c) (c *)sound_inst(#c)
202
#endif
203
#if !defined(SOUND_FREE)
204
#define SOUND_FREE(itm) {			 \
205
  if (itm != NULL) {				 \
206
    if ( (*itm->__destructor) != NULL ) {	 \
207
      (*itm->__destructor)((void *)itm);	 \
208
    }						 \
209
    itm = NULL; 				 \
210
  }						 \
211
}
212
#endif
213
214
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/stream_list.h (+140 lines)
Line 0    Link Here 
1
#if !defined(__XRDP_STREAM_LIST__)
2
#define __XRDP_STREAM_LIST__
3
4
5
#include <stdlib.h>
6
#include <stdio.h>
7
8
#include "arch.h"
9
#include "defines.h"
10
#include "os_calls.h"
11
#include "parse.h"
12
#if defined(__XRDP_STREAM_LIST_THREADS__)
13
#include "thread_calls.h"
14
#include "thread_macros.h"
15
#endif
16
17
struct stream_list;
18
19
typedef struct stream_list {
20
	struct stream *		s;
21
	struct stream_list *	next;
22
	struct stream_list *	prev;
23
#if defined(__XRDP_STREAM_LIST_THREADS__)
24
	tc_t			lock;
25
#endif
26
} stream_list_t, * stream_list_p;
27
28
29
30
#define SQ_CREATE()	(stream_list_t *)g_malloc(sizeof(stream_list_t), 1)
31
#if defined(__XRDP_STREAM_LIST_THREADS__)
32
#define SQ_INIT(x)			{				\
33
  if (x != NULL) {							\
34
    tc_t	l_tattr;						\
35
    tc_p	p_tattr = (tc_p)(&l_tattr);				\
36
    g_memset((void *)(&l_tattr),0,sizeof(tc_t));			\
37
    TC_MUTATTR_INIT((tc_p)p_tattr);					\
38
    /* TC_MUTEX_INIT((tc_p)(&(x->lock)), (tc_p)p_tattr); */		\
39
  }									\
40
}
41
#else
42
#define SQ_INIT(x)	0
43
#endif
44
#define DECLARE_SQ(inx)						\
45
  stream_list_t * inx = (stream_list_t *)NULL;			\
46
  {									\
47
    inx = SQ_CREATE();						\
48
    if (inx != NULL) {							\
49
       SQ_INIT(inx);						\
50
    }									\
51
  }									
52
#define SQ_ENQ(t,x)			{ 				\
53
  if (t == NULL) {						\
54
    t = x;							\
55
    if (t != NULL) {						\
56
      t->prev = NULL;						\
57
      t->next = NULL;						\
58
    }									\
59
  }									\
60
  else {								\
61
    stream_list_t * tlmp = (stream_list_t *)NULL;			\
62
    tlmp = t;							\
63
    while (tlmp != NULL && tlmp->next != NULL) {			\
64
      tlmp = tlmp->next;						\
65
    }									\
66
    tlmp->next = x;							\
67
    if (x != NULL) {							\
68
      x->prev = tlmp;							\
69
      x->next = NULL;							\
70
    }									\
71
  }									\
72
}
73
#define SQ_DEQ(t,x)			{				\
74
  if (x != NULL) {							\
75
    (*(x)) = t;								\
76
    if ((*(x)) != NULL) {						\
77
      (*(x))->prev = NULL;						\
78
      (*(x))->next = NULL;						\
79
    }									\
80
  }									\
81
  if (t != NULL) {							\
82
    t = t->next;							\
83
    if (t != NULL) {							\
84
      t->prev = NULL;							\
85
    }									\
86
  }									\
87
}
88
#define SQ_FIND(t, x, y, z)		{				\
89
    if (t == NULL) {						\
90
      z = NULL;								\
91
    }									\
92
    else {								\
93
      int tdone = 0;							\
94
      stream_list_t * tlmp = (stream_list_t *)NULL;			\
95
      z = tlmp;								\
96
      tlmp = t;						\
97
      if (tlmp != NULL && tlmp->device_id == x && tlmp->opid == y) {	\
98
	z = tlmp;							\
99
	tdone = 1;							\
100
      }									\
101
      while (tlmp != NULL && tdone < 1) {				\
102
	if (tlmp->device_id == x && tlmp->opid == y) {			\
103
	  z = tlmp;							\
104
	  tdone = 1;							\
105
	}								\
106
	else {								\
107
	  tlmp = tlmp->next;						\
108
	}								\
109
      }									\
110
    }									\
111
}
112
#define SQ_CUT(t, x)	{						\
113
    if (x != NULL) {							\
114
      if (x->prev == NULL) {						\
115
	t = t->next;				\
116
	if (t != NULL) {					\
117
	  t->prev = NULL;					\
118
	}								\
119
      }									\
120
      else if (x->prev != NULL) {					\
121
	x->prev->next = x->next;					\
122
	if (x->next != NULL) {						\
123
	  x->next->prev = x->prev;					\
124
	}								\
125
      }									\
126
    }									\
127
}
128
#define SQ_COUNT(t, x)		{					\
129
	stream_list_t * tmp = t;					\
130
	x = 0;								\
131
	while (tmp != NULL) {						\
132
	  x++;								\
133
	  tmp = tmp->next;						\
134
	}								\
135
}
136
137
138
139
140
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/stringlist.c (+127 lines)
Line 0    Link Here 
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include "stringlist.h"
4
#include "os_calls.h"
5
#include "dbg.h"
6
7
strlist * strlist_init(void) {
8
  strlist * ret = (strlist *)NULL;
9
  return ret;
10
}
11
12
strlist * strlist_empty(void) {
13
  strlist * ret = (strlist *)NULL;
14
  ret = (strlist *)g_malloc(sizeof(strlist),1);
15
  g_memset(ret,0,sizeof(strlist));
16
  ret->str = (char *)NULL;
17
  ret->next = (void *)NULL;
18
  return ret;
19
}
20
21
strlist * strlist_append(strlist ** self, const char * text) {
22
  int n = 0;
23
  strlist * itm = (strlist *)NULL;
24
  strlist * final = (strlist *)NULL;
25
  strlist * ret = (strlist *)NULL;
26
  ret = *self;
27
  final = *self;
28
  itm = strlist_empty();
29
  itm->str = g_strdup(text);
30
  itm->next = (void *)NULL;
31
  if (final == NULL) {
32
    ret = itm;
33
  }
34
  else {
35
    while (final->next != NULL) {
36
      final = (strlist *)final->next;
37
      n++;
38
    }
39
    final->next = (void *)itm;
40
    ret = *self;
41
  }
42
  return ret;
43
}
44
45
strlist * strlist_remove(strlist ** self, strlist * itm) {
46
  unsigned int found = 0;
47
  strlist * prev = (strlist *)NULL;
48
  strlist * cur = (strlist *)NULL;
49
  strlist * ret = (strlist *)NULL;
50
  cur = *self;
51
  ret = *self;
52
  if (cur != NULL) {
53
    while (cur->next != NULL && found == 0) {
54
      if (cur == itm) {
55
	found = 1;
56
      }
57
      prev = cur;
58
      cur = (strlist *)cur->next;
59
    }
60
    if (found == 1) {
61
      prev->next = cur->next;
62
      g_free(cur->str);
63
      cur->str = (char *)NULL;
64
      g_free(cur);
65
    }
66
  }
67
  return ret;
68
}
69
70
strlist * strlist_find(strlist * self, const char * text) {
71
  unsigned int found = 0;
72
  strlist * ret = (strlist *)NULL;
73
  if (text != NULL) {
74
    ret = self;
75
  }
76
  while (ret != NULL && found == 0) {
77
    found = g_strcmp(text,ret->str);
78
    ret = (strlist *)ret->next;
79
  }
80
  return ret;
81
}
82
83
int strlist_count(strlist * self) {
84
  int ret = 0;
85
  while (self != NULL) {
86
    ret++;
87
    self = (strlist *)self->next;
88
  }
89
  return ret;
90
}
91
92
strlist * strlist_free(strlist * self) {
93
  strlist * itm = (strlist *)NULL;
94
  strlist * prev = (strlist *)NULL;
95
  itm = self;
96
  while (itm != NULL) {
97
    prev = itm;
98
    itm = (strlist *)itm->next;
99
    g_free(prev->str);
100
    prev->next = (void *)NULL;
101
    g_free(prev);
102
  }
103
  return NULL;
104
}
105
106
char ** strlist_to_array(strlist * self, int * count) {
107
  char ** ret = (char **)NULL;
108
  int idx = 0;
109
  *count = strlist_count(self);
110
  ret = (char **)g_malloc((*count + 1),1);
111
  while (self != NULL) {
112
    ret[idx] = g_strdup(self->str);
113
    self = (strlist *)self->next;
114
    idx++;
115
  }
116
  return ret;
117
}
118
119
strlist * array_to_strlist(const char ** arr, int count) {
120
  strlist * ret = (strlist *)NULL;
121
  int idx = 0;
122
  ret = strlist_init();
123
  for (idx = 0;idx < count;idx++) {
124
    ret = strlist_append(&ret, arr[idx]);
125
  }
126
  return ret;
127
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/stringlist.h (+22 lines)
Line 0    Link Here 
1
#ifndef __strlist__
2
#define __strlist__
3
4
#include <stdio.h>
5
#include <string.h>
6
7
typedef struct {
8
  char * str;
9
  void * next;
10
} strlist;
11
12
strlist * strlist_init(void);
13
strlist * strlist_empty(void);
14
strlist * strlist_append(strlist **, const char *);
15
strlist * strlist_remove(strlist **, strlist *);
16
strlist * strlist_free(strlist *);
17
strlist * strlist_find(strlist *, const char *);
18
int strlist_count(strlist *);
19
char ** strlist_to_array(strlist *, int *);
20
strlist * array_to_strlist(const char **, int);
21
22
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/thread_calls.c (-42 / +930 lines)
 Lines 28-47    Link Here 
28
#else
28
#else
29
#include <pthread.h>
29
#include <pthread.h>
30
#include <semaphore.h>
30
#include <semaphore.h>
31
#include <stdint.h>
32
#include <time.h>
31
#endif
33
#endif
32
#include "arch.h"
34
#include "arch.h"
33
#include "thread_calls.h"
35
#include "thread_calls.h"
34
#include "os_calls.h"
36
#include "os_calls.h"
35
37
38
36
/*****************************************************************************/
39
/*****************************************************************************/
37
/* returns error */
40
/* returns error */
38
#if defined(_WIN32)
41
#if defined(_WIN32)
39
int APP_CC
42
tc_thread_t APP_CC
40
tc_thread_create(unsigned long (__stdcall * start_routine)(void*), void* arg)
43
tc_thread_create(unsigned long (__stdcall * start_routine)(void*), void* arg)
41
{
44
{
42
  DWORD thread_id;
45
  int rv = 0;
43
  HANDLE thread;
46
  DWORD thread_id = 0;
44
  int rv;
47
  HANDLE thread = (HANDLE)0;
45
48
46
  /* CreateThread returns handle or zero on error */
49
  /* CreateThread returns handle or zero on error */
47
  thread = CreateThread(0, 0, start_routine, arg, 0, &thread_id);
50
  thread = CreateThread(0, 0, start_routine, arg, 0, &thread_id);
 Lines 50-83    Link Here 
50
  return rv;
53
  return rv;
51
}
54
}
52
#else
55
#else
53
int APP_CC
56
tc_thread_t APP_CC
54
tc_thread_create(void* (* start_routine)(void*), void* arg)
57
tc_thread_create(void * (* start_routine)(void *), void * arg)
55
{
58
{
56
  pthread_t thread;
59
  int rv = 0;
57
  int rv;
60
  pthread_t thread = (pthread_t)0;
61
62
  g_memset(&thread, 0x00, sizeof(pthread_t));
58
63
59
  /* pthread_create returns error */
64
  /* pthread_create returns error */
60
  rv = pthread_create(&thread, 0, start_routine, arg);
65
  rv = pthread_create(&thread, 0, start_routine, arg);
61
  pthread_detach(thread);
66
  if (!rv) {
67
    rv = pthread_detach(thread);
68
  }
69
  return rv;
70
}
71
#endif
72
73
/*****************************************************************************/
74
int APP_CC
75
tc_thread_init_full(tc_thread_t * itid, const tc_threadattr_t * tattrs, void * (* start_routine)(void *), void * targs) {
76
  int rv = 0;
77
  pthread_t * tid = (pthread_t *)NULL;
78
  tid = (pthread_t *)itid;
79
  if (itid == NULL || start_routine == NULL) {
80
    rv = -1;
81
  }
82
  else {
83
#if defined(_WIN32)
84
    DWORD thread_id;
85
    *tid = CreateThread(0, 0, start_routine, targs, 0, &thread_id);
86
#else
87
    rv = pthread_create(tid,tattrs,start_routine,targs);
88
  }
89
#endif
62
  return rv;
90
  return rv;
63
}
91
}
92
93
/*****************************************************************************/
94
int APP_CC
95
tc_thread_init(tc_thread_t * itid, void * (* start_routine)(void *), void * targs) {
96
  int rv = 0;
97
  pthread_t * tid = (pthread_t *)NULL;
98
  tid = (pthread_t *)itid;
99
  if (itid == NULL || start_routine == NULL) {
100
    rv = -1;
101
  }
102
  else {
103
#if defined(_WIN32)
104
    DWORD thread_id;
105
    *tid = CreateThread(0, 0, start_routine, arg, 0, &thread_id);
106
#else
107
    pthread_attr_t lattr;
108
    g_memset(&lattr,0,sizeof(pthread_attr_t));
109
    pthread_attr_init(&lattr);
110
    pthread_attr_setdetachstate(&lattr, PTHREAD_CREATE_JOINABLE);
111
    rv = pthread_create(tid,&lattr,start_routine,targs);
64
#endif
112
#endif
113
  }
114
  return rv;
115
}
116
117
/*****************************************************************************/
118
int APP_CC
119
tc_thread_join(tc_thread_t itid, void ** inarg) {
120
  int rv = 0;
121
#if defined(_WIN32)
122
  HANDLE tid;
123
  tid = (HANDLE)itid;
124
  WaitForSingleObject(tid, INFINITE);
125
#else
126
  pthread_t tid;
127
  g_memset(&tid, 0, sizeof(pthread_t));
128
  tid = (pthread_t)itid;
129
  rv = pthread_join(tid, inarg);
130
#endif
131
  return rv;
132
}
133
134
/*****************************************************************************/
135
void APP_CC
136
tc_thread_exit(void * arg) {
137
#if defined(_WIN32)
138
#else
139
  pthread_exit(arg);
140
#endif
141
}
142
143
/*****************************************************************************/
144
int APP_CC
145
tc_thread_signal(tc_thread_t arg, int sig) {
146
    return pthread_kill(arg, sig);
147
}
65
148
66
/*****************************************************************************/
149
/*****************************************************************************/
67
tbus APP_CC
150
tc_thread_t APP_CC
68
tc_get_threadid(void)
151
tc_get_threadid(void)
69
{
152
{
70
#if defined(_WIN32)
153
#if defined(_WIN32)
71
  return (tbus)GetCurrentThreadId();
154
  return (tc_thread_t)GetCurrentThreadId();
72
#else
155
#else
73
  return (tbus)pthread_self();
156
  return (tc_thread_t)pthread_self();
74
#endif
157
#endif
75
}
158
}
76
159
77
/*****************************************************************************/
160
/*****************************************************************************/
78
/* returns boolean */
161
/* returns boolean */
79
int APP_CC
162
int APP_CC
80
tc_threadid_equal(tbus tid1, tbus tid2)
163
tc_threadid_equal(tc_thread_t tid1, tc_thread_t tid2)
81
{
164
{
82
#if defined(_WIN32)
165
#if defined(_WIN32)
83
  return tid1 == tid2;
166
  return tid1 == tid2;
 Lines 87-168    Link Here 
87
}
170
}
88
171
89
/*****************************************************************************/
172
/*****************************************************************************/
90
tbus APP_CC
173
int APP_CC
174
tc_mutex_init(tc_p ival, tc_p args) {
175
  int rv = 0;
176
#if defined(_WIN32)
177
#else
178
  pthread_mutex_t * lmutex = (pthread_mutex_t *)NULL;
179
  pthread_mutexattr_t *lattr = (pthread_mutexattr_t *)NULL;
180
181
  if (ival == NULL) {
182
    rv = -1;
183
  }
184
  else {
185
    lmutex = (pthread_mutex_t *)(ival);
186
    lattr = (pthread_mutexattr_t *)(args);
187
  }
188
  if (lattr == NULL) {
189
    pthread_mutexattr_t tattr;
190
    g_memset(&tattr,0,sizeof(pthread_mutexattr_t));
191
    lattr = &tattr;
192
    pthread_mutexattr_init(lattr);
193
    pthread_mutexattr_settype(lattr, TC_MUTEX_ERRORCHECK);
194
  }
195
  if (lmutex != NULL) {
196
    rv = pthread_mutex_init(lmutex, lattr);
197
  }
198
#endif
199
  return rv;
200
}
201
202
/*****************************************************************************/
203
tc_p APP_CC
91
tc_mutex_create(void)
204
tc_mutex_create(void)
92
{
205
{
93
#if defined(_WIN32)
206
#if defined(_WIN32)
94
  return (tbus)CreateMutex(0, 0, 0);
207
  return (tc_p)CreateMutex(0, 0, 0);
95
#else
208
#else
96
  pthread_mutex_t* lmutex;
209
  tc_p rv = (tc_p)NULL;
210
  //pthread_mutex_t * lmutex = (pthread_mutex_t *)NULL;
211
  tc_p lmutex = (tc_p)NULL;
97
212
98
  lmutex = (pthread_mutex_t*)g_malloc(sizeof(pthread_mutex_t), 0);
213
  lmutex = (tc_p)g_malloc(sizeof(pthread_mutex_t), 1);
99
  pthread_mutex_init(lmutex, 0);
214
  if (lmutex != NULL) {
100
  return (tbus)lmutex;
215
    if (!tc_mutex_init(lmutex, NULL)) {
216
      rv = (tc_p)lmutex;
217
    }
218
  }
219
  return rv;
101
#endif
220
#endif
102
}
221
}
103
222
104
/*****************************************************************************/
223
/*****************************************************************************/
105
void APP_CC
224
int APP_CC
106
tc_mutex_delete(tbus mutex)
225
tc_mutex_delete(tc_p mutex)
226
{
227
  int rv = 0;
228
#if defined(_WIN32)
229
  rv = CloseHandle((HANDLE)mutex);
230
#else
231
  if (mutex != NULL) {
232
    pthread_mutex_t * lmutex = (pthread_mutex_t *)NULL;
233
    lmutex = (pthread_mutex_t *)(mutex);
234
    rv = pthread_mutex_destroy(lmutex);
235
  }
236
#endif
237
  return rv;
238
}
239
240
/*****************************************************************************/
241
int APP_CC
242
tc_mutex_deinit(tc_p mutex)
107
{
243
{
244
  int rv = 0;
108
#if defined(_WIN32)
245
#if defined(_WIN32)
109
  CloseHandle((HANDLE)mutex);
246
  rv = CloseHandle((HANDLE)mutex);
110
#else
247
#else
111
  pthread_mutex_t* lmutex;
248
  if (mutex != NULL) {
249
    pthread_mutex_t * lmutex = (pthread_mutex_t *)NULL;
250
    lmutex = (pthread_mutex_t *)(mutex);
251
    rv = pthread_mutex_destroy(lmutex);
252
  }
253
#endif
254
  return rv;
255
}
112
256
113
  lmutex = (pthread_mutex_t*)mutex;
257
/*****************************************************************************/
114
  pthread_mutex_destroy(lmutex);
258
int APP_CC
115
  g_free(lmutex);
259
tc_mutex_lock(tc_p mutex)
260
{
261
  int rv = 0;
262
#if defined(_WIN32)
263
  WaitForSingleObject((HANDLE)mutex, INFINITE);
264
#else
265
  if (mutex == NULL) {
266
    rv = -1;
267
  }
268
  else {
269
    rv = pthread_mutex_lock((pthread_mutex_t *)(mutex));
270
  }
116
#endif
271
#endif
272
  return rv;
117
}
273
}
118
274
119
/*****************************************************************************/
275
/*****************************************************************************/
120
int APP_CC
276
int APP_CC
121
tc_mutex_lock(tbus mutex)
277
tc_mutex_trylock(tc_p mutex)
122
{
278
{
279
  int rv = 0;
123
#if defined(_WIN32)
280
#if defined(_WIN32)
124
  WaitForSingleObject((HANDLE)mutex, INFINITE);
281
  WaitForSingleObject((HANDLE)mutex, INFINITE);
125
  return 0;
126
#else
282
#else
127
  pthread_mutex_lock((pthread_mutex_t*)mutex);
283
  if (mutex != NULL) {
128
  return 0;
284
    rv = pthread_mutex_trylock((pthread_mutex_t *)mutex);
285
  }
129
#endif
286
#endif
287
  return rv;
130
}
288
}
131
289
132
/*****************************************************************************/
290
/*****************************************************************************/
133
int APP_CC
291
int APP_CC
134
tc_mutex_unlock(tbus mutex)
292
tc_mutex_unlock(tc_p mutex)
135
{
293
{
294
  int rv = 0;
136
#if defined(_WIN32)
295
#if defined(_WIN32)
137
  ReleaseMutex((HANDLE)mutex);
296
  ReleaseMutex((HANDLE)mutex);
138
  return 0;
139
#else
297
#else
140
  pthread_mutex_unlock((pthread_mutex_t*)mutex);
298
  if (mutex != NULL) {
141
  return 0;
299
    rv = pthread_mutex_unlock((pthread_mutex_t *)mutex);
300
  }
301
#endif
302
  return rv;
303
}
304
305
/*****************************************************************************/
306
int APP_CC
307
tc_mutex_timedlock(tc_p mutex, const struct timespec * itime) {
308
  int rv = 0;
309
#if defined(_WIN32)
310
#else
311
  pthread_mutex_t * p_mut = (pthread_mutex_t *)mutex;
312
313
  if (mutex == NULL || itime == NULL) {
314
    rv = -1;
315
  }
316
  else {
317
    rv = pthread_mutex_timedlock(p_mut, itime);
318
  }
142
#endif
319
#endif
320
  return rv;
321
}
322
323
/*****************************************************************************/
324
int APP_CC
325
tc_mutattr_init(tc_p attr) {
326
  int rv = 0;
327
  pthread_mutexattr_t * tattr = (pthread_mutexattr_t *)NULL;
328
  if (attr == NULL) {
329
    rv = -1;
330
  }
331
  else {
332
    tattr = (pthread_mutexattr_t *)attr;
333
    rv = pthread_mutexattr_init(tattr);
334
  }
335
  return rv;
336
}
337
338
/*****************************************************************************/
339
int APP_CC
340
tc_mutattr_settype(tc_p attr, int itype) {
341
  int rv = 0;
342
  pthread_mutexattr_t * tattr = (pthread_mutexattr_t *)NULL;
343
  if (attr == NULL) {
344
    rv = -1;
345
  }
346
  else {
347
    tattr = (pthread_mutexattr_t *)attr;
348
    rv = pthread_mutexattr_settype(tattr, itype);
349
  }
350
  return rv;
143
}
351
}
144
352
145
/*****************************************************************************/
353
/*****************************************************************************/
146
tbus APP_CC
354
int APP_CC
355
tc_mutattr_gettype(tc_p attr) {
356
  int rv = 0;
357
  pthread_mutexattr_t * tattr = (pthread_mutexattr_t *)NULL;
358
  if (attr == NULL) {
359
    rv = -1;
360
  }
361
  else {
362
    tattr = (pthread_mutexattr_t *)attr;
363
    //rv = pthread_mutexattr_gettype(tattr);
364
  }
365
  return rv;
366
}
367
368
/*****************************************************************************/
369
int APP_CC
370
tc_mutattr_setpshared(tc_p attr, int ipshared) {
371
  int rv = 0;
372
  pthread_mutexattr_t * tattr = (pthread_mutexattr_t *)NULL;
373
  if (attr == NULL) {
374
    rv = -1;
375
  }
376
  else {
377
    tattr = (pthread_mutexattr_t *)attr;
378
    rv = pthread_mutexattr_setpshared(tattr, ipshared);
379
  }
380
  return rv;
381
}
382
383
/*****************************************************************************/
384
int APP_CC
385
tc_mutattr_getpshared(const tc_p attr, int * ipshared) {
386
  int rv = 0;
387
  if (attr == NULL) {
388
    rv = -1;
389
  }
390
  else {
391
    int lv = 0;
392
    const pthread_mutexattr_t * tattr = (const pthread_mutexattr_t *)attr;
393
    rv = pthread_mutexattr_getpshared(tattr, &lv);
394
    if (ipshared == NULL) {
395
      rv = lv;
396
    }
397
    else {
398
      *ipshared = lv;
399
    }
400
  }
401
  return rv;
402
}
403
404
/*****************************************************************************/
405
int APP_CC
406
tc_mutattr_setprotocol(tc_p attr, int iproto) {
407
  int rv = 0;
408
  pthread_mutexattr_t * tattr = (pthread_mutexattr_t *)NULL;
409
  if (attr == NULL) {
410
    rv = -1;
411
  }
412
  else {
413
    tattr = (pthread_mutexattr_t *)attr;
414
    rv = pthread_mutexattr_setprotocol(tattr, iproto);
415
  }
416
  return rv;
417
}
418
419
/*****************************************************************************/
420
int APP_CC
421
tc_mutattr_getprotocol(tc_p attr) {
422
  int rv = 0;
423
  pthread_mutexattr_t * tattr = (pthread_mutexattr_t *)NULL;
424
  if (attr == NULL) {
425
    rv = -1;
426
  }
427
  else {
428
    tattr = (pthread_mutexattr_t *)attr;
429
    //rv = pthread_mutexattr_getprotocol(tattr);
430
  }
431
  return rv;
432
}
433
434
/*****************************************************************************/
435
int APP_CC
436
tc_mutattr_destroy(tc_p attr) {
437
  int rv = 0;
438
  pthread_mutexattr_t * tattr = (pthread_mutexattr_t *)NULL;
439
  if (attr == NULL) {
440
    rv = -1;
441
  }
442
  else {
443
    tattr = (pthread_mutexattr_t *)attr;
444
    rv = pthread_mutexattr_destroy(tattr);
445
  }
446
  return rv;
447
}
448
449
/*****************************************************************************/
450
tc_p APP_CC
147
tc_sem_create(int init_count)
451
tc_sem_create(int init_count)
148
{
452
{
149
#if defined(_WIN32)
453
#if defined(_WIN32)
150
  HANDLE sem;
454
  HANDLE sem;
151
455
152
  sem = CreateSemaphore(0, init_count, init_count + 10, 0);
456
  sem = CreateSemaphore(0, init_count, init_count + 10, 0);
153
  return (tbus)sem;
457
  return (tc_p)sem;
154
#else
458
#else
155
  sem_t* sem;
459
  sem_t * sem = (sem_t *)NULL;
156
460
157
  sem = g_malloc(sizeof(sem_t), 0);
461
  sem = (sem_t *)g_malloc(sizeof(sem_t), 0);
158
  sem_init(sem, 0, init_count);
462
  sem_init(sem, 0, init_count);
159
  return (tbus)sem;
463
  return (tc_p)sem;
160
#endif
464
#endif
161
}
465
}
162
466
163
/*****************************************************************************/
467
/*****************************************************************************/
164
void APP_CC
468
void APP_CC
165
tc_sem_delete(tbus sem)
469
tc_sem_delete(tc_p sem)
166
{
470
{
167
#if defined(_WIN32)
471
#if defined(_WIN32)
168
  CloseHandle((HANDLE)sem);
472
  CloseHandle((HANDLE)sem);
 Lines 176-183    Link Here 
176
}
480
}
177
481
178
/*****************************************************************************/
482
/*****************************************************************************/
483
void APP_CC
484
tc_sem_deinit(tc_p sem)
485
{
486
#if defined(_WIN32)
487
  CloseHandle((HANDLE)sem);
488
#else
489
  sem_t* lsem;
490
491
  lsem = (sem_t*)sem;
492
  sem_destroy(lsem);
493
#endif
494
}
495
496
/*****************************************************************************/
179
int APP_CC
497
int APP_CC
180
tc_sem_dec(tbus sem)
498
tc_sem_dec(tc_p sem)
181
{
499
{
182
#if defined(_WIN32)
500
#if defined(_WIN32)
183
  WaitForSingleObject((HANDLE)sem, INFINITE);
501
  WaitForSingleObject((HANDLE)sem, INFINITE);
 Lines 190-196    Link Here 
190
508
191
/*****************************************************************************/
509
/*****************************************************************************/
192
int APP_CC
510
int APP_CC
193
tc_sem_inc(tbus sem)
511
tc_sem_inc(tc_p sem)
194
{
512
{
195
#if defined(_WIN32)
513
#if defined(_WIN32)
196
  ReleaseSemaphore((HANDLE)sem, 1, 0);
514
  ReleaseSemaphore((HANDLE)sem, 1, 0);
 Lines 200-202    Link Here 
200
  return 0;
518
  return 0;
201
#endif
519
#endif
202
}
520
}
521
522
/*****************************************************************************/
523
int APP_CC
524
tc_cond_create(tc_p icv, const tc_p ica) {
525
  int rv = 0;
526
  pthread_cond_t * cv = (pthread_cond_t *)NULL;
527
  cv = (pthread_cond_t *)icv;
528
#if defined(_WIN32)
529
  cv->waiters_count_ = 0;
530
  cv->was_broadcast_ = 0;
531
  cv->sema_ = CreatedSemaphore (NULL,       // no security
532
                                0,          // initially 0
533
                                0x7fffffff, // max count
534
                                NULL);      // unnamed 
535
  InitializeCriticalSection (&cv->waiters_count_lock_);
536
  cv->waiters_done_ = CreateEvent (NULL,  // no security
537
                                   FALSE, // auto-reset
538
                                   FALSE, // non-signaled initially
539
                                   NULL); // unnamed
540
#else
541
  if (cv == NULL) {
542
    rv = -1;
543
  }
544
  else {
545
    const pthread_condattr_t * ca = (pthread_condattr_t *)ica;
546
    rv = pthread_cond_init(cv, ca);
547
  }
548
#endif
549
  return rv;
550
}
551
552
/*****************************************************************************/
553
int APP_CC tc_cond_wait (tc_p icv, tc_p iem) {
554
  int rv = 0;
555
  pthread_cond_t * cv = (pthread_cond_t *)NULL;
556
  pthread_mutex_t * external_mutex = (pthread_mutex_t *)NULL;
557
  cv = (pthread_cond_t *)icv;
558
  external_mutex = (pthread_mutex_t *)iem;
559
#if defined(_WIN32)
560
  // Avoid race conditions.
561
  EnterCriticalSection (&cv->waiters_count_lock_);
562
  cv->waiters_count_++;
563
  LeaveCriticalSection (&cv->waiters_count_lock_);
564
565
  // This call atomically releases the mutex and waits on the
566
  // semaphore until <pthread_cond_signal> or <pthread_cond_broadcast>
567
  // are called by another thread.
568
  SignalObjectAndWait (*external_mutex, cv->sema_, INFINITE, FALSE);
569
570
  // Reacquire lock to avoid race conditions.
571
  EnterCriticalSection (&cv->waiters_count_lock_);
572
573
  // We're no longer waiting...
574
  cv->waiters_count_--;
575
576
  // Check to see if we're the last waiter after <pthread_cond_broadcast>.
577
  int last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0;
578
579
  LeaveCriticalSection (&cv->waiters_count_lock_);
580
581
  // If we're the last waiter thread during this particular broadcast
582
  // then let all the other threads proceed.
583
  if (last_waiter)
584
    // This call atomically signals the <waiters_done_> event and waits until
585
    // it can acquire the <external_mutex>.  This is required to ensure fairness. 
586
    SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE);
587
  else
588
    // Always regain the external mutex since that's the guarantee we
589
    // give to our callers. 
590
    WaitForSingleObject (*external_mutex);
591
#else
592
  if (cv == NULL || external_mutex == NULL) {
593
    rv = -1;
594
  }
595
  else {
596
    rv = pthread_cond_wait(cv, external_mutex);
597
  }
598
#endif
599
  return rv;
600
}
601
602
/*****************************************************************************/
603
int APP_CC tc_cond_timedwait (tc_p icv, tc_p iem, tc_future_t tos) {
604
  int rv = 0;
605
  pthread_cond_t * cv = (pthread_cond_t *)NULL;
606
  pthread_mutex_t * external_mutex = (pthread_mutex_t *)NULL;
607
  cv = (pthread_cond_t *)icv;
608
  external_mutex = (pthread_mutex_t *)iem;
609
#if defined(_WIN32)
610
  // Avoid race conditions.
611
  EnterCriticalSection (&cv->waiters_count_lock_);
612
  cv->waiters_count_++;
613
  LeaveCriticalSection (&cv->waiters_count_lock_);
614
615
  // This call atomically releases the mutex and waits on the
616
  // semaphore until <pthread_cond_signal> or <pthread_cond_broadcast>
617
  // are called by another thread.
618
  SignalObjectAndWait (*external_mutex, cv->sema_, INFINITE, FALSE);
619
620
  // Reacquire lock to avoid race conditions.
621
  EnterCriticalSection (&cv->waiters_count_lock_);
622
623
  // We're no longer waiting...
624
  cv->waiters_count_--;
625
626
  // Check to see if we're the last waiter after <pthread_cond_broadcast>.
627
  int last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0;
628
629
  LeaveCriticalSection (&cv->waiters_count_lock_);
630
631
  // If we're the last waiter thread during this particular broadcast
632
  // then let all the other threads proceed.
633
  if (last_waiter)
634
    // This call atomically signals the <waiters_done_> event and waits until
635
    // it can acquire the <external_mutex>.  This is required to ensure fairness. 
636
    SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE);
637
  else
638
    // Always regain the external mutex since that's the guarantee we
639
    // give to our callers. 
640
    WaitForSingleObject (*external_mutex);
641
#else
642
  if (tos < 0 || cv == NULL || external_mutex == NULL) {
643
    rv = -1;
644
  }
645
  else {
646
    struct timespec lts;
647
    struct timespec * ts = (struct timespec *)(&lts);
648
    g_memset(ts,0,sizeof(struct timespec));
649
    ts->tv_sec = (long int)tos;
650
    rv = pthread_cond_timedwait(cv, external_mutex, ts);
651
  }
652
#endif
653
  return rv;
654
}
655
656
/*****************************************************************************/
657
int APP_CC tc_cond_signal (tc_p icv) {
658
  int rv = 0;
659
  pthread_cond_t * cv = (pthread_cond_t *)NULL;
660
  cv = (pthread_cond_t *)icv;
661
#if defined(_WIN32)
662
  EnterCriticalSection (&cv->waiters_count_lock_);
663
  int have_waiters = cv->waiters_count_ > 0;
664
  LeaveCriticalSection (&cv->waiters_count_lock_);
665
666
  // If there aren't any waiters, then this is a no-op.  
667
  if (have_waiters)
668
    ReleaseSemaphore (cv->sema_, 1, 0);
669
#else
670
  if (cv == NULL) {
671
    rv = -1;
672
  }
673
  else {
674
    rv = pthread_cond_signal(cv);
675
  }
676
#endif
677
  return rv;
678
}
679
680
/*****************************************************************************/
681
int APP_CC tc_cond_broadcast (tc_p icv) {
682
  int rv = 0;
683
  pthread_cond_t * cv = (pthread_cond_t *)NULL;
684
  cv = (pthread_cond_t *)icv;
685
#if defined(_WIN32)
686
  int have_waiters = 0;
687
  // This is needed to ensure that <waiters_count_> and <was_broadcast_> are
688
  // consistent relative to each other.
689
  EnterCriticalSection (&cv->waiters_count_lock_);
690
691
  if (cv->waiters_count_ > 0) {
692
    // We are broadcasting, even if there is just one waiter...
693
    // Record that we are broadcasting, which helps optimize
694
    // <pthread_cond_wait> for the non-broadcast case.
695
    cv->was_broadcast_ = 1;
696
    have_waiters = 1;
697
  }
698
699
  if (have_waiters) {
700
    // Wake up all the waiters atomically.
701
    ReleaseSemaphore (cv->sema_, cv->waiters_count_, 0);
702
703
    LeaveCriticalSection (&cv->waiters_count_lock_);
704
705
    // Wait for all the awakened threads to acquire the counting
706
    // semaphore. 
707
    WaitForSingleObject (cv->waiters_done_, INFINITE);
708
    // This assignment is okay, even without the <waiters_count_lock_> held 
709
    // because no other waiter threads can wake up to access it.
710
    cv->was_broadcast_ = 0;
711
  }
712
  else {
713
    LeaveCriticalSection (&cv->waiters_count_lock_);
714
  }
715
#else
716
  if (cv == NULL) {
717
    rv = -1;
718
  }
719
  else {
720
    rv = pthread_cond_broadcast(cv);
721
  }
722
#endif
723
  return rv;
724
}
725
726
/*****************************************************************************/
727
int APP_CC tc_cond_delete(tc_p cv) {
728
  int rv = 0;
729
  if (cv == 0) {
730
    rv = -1;
731
  }
732
  else {
733
#if defined(_WIN32)
734
  CloseHandle(((pthread_cond_t *)cv)->sema_);
735
  CloseHandle(((pthread_cond_t *)cv)->waiters_done_);
736
#else
737
  pthread_cond_t * lcv = (pthread_cond_t *)NULL;
738
  lcv = (pthread_cond_t *)cv;
739
  rv = pthread_cond_destroy(lcv);
740
#endif
741
  }
742
  return rv;
743
}
744
745
/*****************************************************************************/
746
int APP_CC tc_cond_deinit(tc_p cv) {
747
  int rv = 0;
748
  if (cv == 0) {
749
    rv = -1;
750
  }
751
  else {
752
#if defined(_WIN32)
753
  CloseHandle(((pthread_cond_t *)cv)->sema_);
754
  CloseHandle(((pthread_cond_t *)cv)->waiters_done_);
755
#else
756
  pthread_cond_t * lcv = (pthread_cond_t *)NULL;
757
  lcv = (pthread_cond_t *)cv;
758
  rv = pthread_cond_destroy(lcv);
759
#endif
760
  }
761
  return rv;
762
}
763
764
/*****************************************************************************/
765
int APP_CC tc_condattr_init(tc_p cv) {
766
  int rv = 0;
767
  if (cv == NULL) {
768
    rv = -1;
769
  }
770
  else {
771
    pthread_condattr_t * tcv = (pthread_condattr_t *)cv;
772
    rv = pthread_condattr_init(tcv);
773
  }
774
  return rv;
775
}
776
777
/*****************************************************************************/
778
int APP_CC tc_condattr_deinit(tc_p cv) {
779
  int rv = 0;
780
  if (cv == NULL) {
781
    rv = -1;
782
  }
783
  else {
784
    pthread_condattr_t * tcv = (pthread_condattr_t *)cv;
785
    rv = pthread_condattr_destroy(tcv);
786
  }
787
  return rv;
788
}
789
790
int APP_CC tc_condattr_getpshared(const tc_p cv, int * ipsh) {
791
  int rv = 0;
792
  if (cv == NULL) {
793
    rv = -1;
794
  }
795
  else {
796
    const pthread_condattr_t * tcv = (const pthread_condattr_t *)cv;
797
    rv = pthread_condattr_getpshared(tcv, ipsh);
798
  }
799
  return rv;
800
}
801
802
int APP_CC tc_condattr_setpshared(tc_p cv, int ipsh) {
803
  int rv = 0;
804
  if (cv == NULL) {
805
    rv = -1;
806
  }
807
  else {
808
    pthread_condattr_t * tcv = (pthread_condattr_t *)cv;
809
    rv = pthread_condattr_setpshared(tcv, ipsh);
810
  }
811
  return rv;
812
}
813
814
/*****************************************************************************/
815
int APP_CC
816
tc_threadattr_init(tc_p attr) {
817
  if (attr == NULL) {
818
    return -1;
819
  }
820
  else {
821
    return pthread_attr_init((pthread_attr_t *)attr);
822
  }
823
}
824
825
/*****************************************************************************/
826
int APP_CC
827
tc_threadattr_getdetachstate(const tc_p attr, int * st) {
828
  if (attr == NULL || st == NULL) {
829
    return -1;
830
  }
831
  else {
832
    return pthread_attr_getdetachstate((const pthread_attr_t *)attr, st);
833
  }
834
}
835
836
/*****************************************************************************/
837
int APP_CC
838
tc_threadattr_setdetachstate(tc_p attr, int st) {
839
  if (attr == NULL) {
840
    return -1;
841
  }
842
  else {
843
    return pthread_attr_setdetachstate((pthread_attr_t *)attr, st);
844
  }
845
}
846
847
/*****************************************************************************/
848
int APP_CC
849
tc_threadattr_getscope(const tc_p attr, int * sc) {
850
  if (attr == NULL) {
851
    return -1;
852
  }
853
  else {
854
    return pthread_attr_getscope((const pthread_attr_t *)attr, sc);
855
  }
856
}
857
858
/*****************************************************************************/
859
int APP_CC
860
tc_threadattr_setscope(tc_p attr, int sc) {
861
  if (attr == NULL) {
862
    return -1;
863
  }
864
  else {
865
    return pthread_attr_setscope((pthread_attr_t *)attr, sc);
866
  }
867
}
868
869
/*****************************************************************************/
870
int APP_CC tc_threadattr_setstacksize(tc_p ta, size_t len) {
871
    int rv = 0;
872
    rv = pthread_attr_setstacksize((pthread_attr_t *)ta, len);
873
    return rv;
874
}
875
876
/*****************************************************************************/
877
int APP_CC tc_threadattr_getstacksize(tc_p ta, size_t * plen) {
878
    int rv = 0;
879
    rv = pthread_attr_getstacksize((pthread_attr_t *)ta, plen);
880
    return rv;
881
}
882
883
#if defined(__USE_XOPEN2K)
884
885
/*****************************************************************************/
886
int APP_CC
887
tc_barrattr_init(tc_p arg) {
888
    int rv = 0;
889
    if (arg == NULL) {
890
      rv = -1;
891
    }
892
    else {
893
      rv = pthread_barrierattr_init((pthread_barrierattr_t *)arg);
894
    }
895
    return rv;
896
}
897
898
/*****************************************************************************/
899
int APP_CC
900
tc_barrattr_setpshared(tc_p arg, int val) {
901
    int rv = 0;
902
    if (arg == NULL) {
903
      rv = -1;
904
    }
905
    else {
906
      rv = pthread_barrierattr_setpshared((pthread_barrierattr_t *)arg, val);
907
    }
908
    return rv;
909
}
910
911
/*****************************************************************************/
912
int APP_CC
913
tc_barrier_init(tc_p arg, int num) {
914
    int rv = 0;
915
    if (arg == NULL || num < 1) {
916
      rv = -1;
917
    }
918
    else {
919
      pthread_barrierattr_t attr;
920
      pthread_barrierattr_t * pattr = &attr;
921
      pthread_barrier_t * a = (pthread_barrier_t *)arg;
922
      if (pattr != NULL) {
923
	g_memset(pattr,0,sizeof(pthread_barrierattr_t));
924
	pthread_barrierattr_init(pattr);
925
	rv = pthread_barrier_init(a, pattr, num);
926
      }
927
      else {
928
	rv = -1;
929
      }
930
    }
931
    return rv;
932
}
933
934
/*****************************************************************************/
935
int APP_CC
936
tc_barrier_init_full(tc_p arg, tc_p attr, int num) {
937
    int rv = 0;
938
    if (arg == NULL || num < 1) {
939
      rv = -1;
940
    }
941
    else {
942
      pthread_barrier_t * a = (pthread_barrier_t *)arg;
943
      pthread_barrierattr_t * b = (pthread_barrierattr_t *)attr;
944
      rv = pthread_barrier_init(a, b, num);
945
    }
946
    return rv;
947
}
948
949
/*****************************************************************************/
950
int APP_CC
951
tc_barrier_deinit(tc_p arg) {
952
    int rv = 0;
953
    if (arg == NULL) {
954
      rv = -1;
955
    }
956
    else {
957
      rv = pthread_barrier_destroy(&(arg->barrier));
958
    }
959
    return rv;
960
}
961
962
/*****************************************************************************/
963
int APP_CC
964
tc_barrier_wait(tc_p arg) {
965
    int rv = 0;
966
    if (arg == NULL) {
967
      rv = -1;
968
    }
969
    else {
970
      rv = pthread_barrier_wait(&(arg->barrier));
971
    }
972
    return rv;
973
}
974
975
/*****************************************************************************/
976
int APP_CC tc_spin_init(tc_p sl) {
977
    int rv = 0;
978
    pthread_spinlock_t * psl = (pthread_spinlock_t *)NULL;
979
980
    if (sl == 0) {
981
      rv = -1;
982
    }
983
    else {
984
      psl = (pthread_spinlock_t *)sl;
985
//      rv = pthread_spin_init(psl, PTHREAD_PROCESS_SHARED);
986
      rv = pthread_spin_init(psl, PTHREAD_PROCESS_PRIVATE);
987
    }
988
989
    return rv;
990
}
991
992
/*****************************************************************************/
993
int APP_CC tc_spin_destroy(tc_p sl) {
994
    int rv = 0;
995
    pthread_spinlock_t * psl = (pthread_spinlock_t *)NULL;
996
997
    if (sl == 0) {
998
      rv = -1;
999
    }
1000
    else {
1001
      psl = (pthread_spinlock_t *)sl;
1002
      rv = pthread_spin_destroy(psl);
1003
    }
1004
1005
    return rv;
1006
}
1007
1008
/*****************************************************************************/
1009
int APP_CC tc_spin_deinit(tc_p sl) {
1010
    int rv = 0;
1011
    pthread_spinlock_t * psl = (pthread_spinlock_t *)NULL;
1012
1013
    if (sl == 0) {
1014
      rv = -1;
1015
    }
1016
    else {
1017
      psl = (pthread_spinlock_t *)sl;
1018
      rv = pthread_spin_destroy(psl);
1019
    }
1020
1021
    return rv;
1022
}
1023
1024
/*****************************************************************************/
1025
int APP_CC tc_spin_lock(tc_p sl) {
1026
    int rv = 0;
1027
    pthread_spinlock_t * psl = (pthread_spinlock_t *)NULL;
1028
1029
    if (sl == 0) {
1030
      rv = -1;
1031
    }
1032
    else {
1033
      psl = (pthread_spinlock_t *)sl;
1034
      rv = pthread_spin_lock(psl);
1035
    }
1036
1037
    return rv;
1038
}
1039
1040
/*****************************************************************************/
1041
int APP_CC tc_spin_unlock(tc_p sl) {
1042
    int rv = 0;
1043
    pthread_spinlock_t * psl = (pthread_spinlock_t *)NULL;
1044
1045
    if (sl == 0) {
1046
      rv = -1;
1047
    }
1048
    else {
1049
      psl = (pthread_spinlock_t *)sl;
1050
      rv = pthread_spin_unlock(psl);
1051
    }
1052
1053
    return rv;
1054
}
1055
1056
/*****************************************************************************/
1057
int APP_CC tc_spin_trylock(tc_p sl) {
1058
    int rv = 0;
1059
    pthread_spinlock_t * psl = (pthread_spinlock_t *)NULL;
1060
1061
    if (sl == 0) {
1062
      rv = -1;
1063
    }
1064
    else {
1065
      psl = (pthread_spinlock_t *)sl;
1066
      rv = pthread_spin_trylock(psl);
1067
    }
1068
1069
    return rv;
1070
}
1071
1072
void * t_malloc(void * mut, size_t len, unsigned char z) {
1073
    void * rv = (void *)NULL;
1074
    TC_MUTEX_LOCK(mut);
1075
    rv = g_malloc(len, z);
1076
    TC_MUTEX_UNLOCK(mut);
1077
    return rv;
1078
}
1079
1080
void t_free(void * mut, void * p) {
1081
    if (p != NULL) {
1082
      TC_MUTEX_LOCK(mut);
1083
      g_free(p);
1084
      TC_MUTEX_UNLOCK(mut);
1085
    }
1086
    return;
1087
}
1088
1089
1090
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/thread_calls.h (-12 / +267 lines)
 Lines 26-54    Link Here 
26
#if !defined(THREAD_CALLS_H)
26
#if !defined(THREAD_CALLS_H)
27
#define THREAD_CALLS_H
27
#define THREAD_CALLS_H
28
28
29
#include <stdint.h>
30
#include <time.h>
31
#include <pthread.h>
32
#include <semaphore.h>
33
#include <signal.h>
34
#include <sys/timeb.h>
35
#include <sys/types.h>
29
#include "arch.h"
36
#include "arch.h"
37
#include "thread_macros.h"
30
38
31
int APP_CC
39
#ifndef MAX_MUTEX
40
#define MAX_MUTEX       25
41
#endif
42
43
44
#if defined(_WIN32)
45
  #if !defined(MAX_EVENTS)
46
  #define MAX_EVENTS 256
47
  #endif
48
typedef HANDLE pthread_t;
49
typedef HANDLE sem_t;
50
typedef HANDLE pthread_mutex_t;
51
typedef int pthread_condattr_t;
52
typedef int pthread_attr_t;
53
typedef int pthread_mutex_t;
54
typedef struct _WIN32_pthread_cond_t {
55
  int waiters_count_;
56
  // Number of waiting threads.
57
58
  CRITICAL_SECTION waiters_count_lock_;
59
  // Serialize access to <waiters_count_>.
60
61
  HANDLE sema_;
62
  // Semaphore used to queue up threads waiting for the condition to
63
  // become signaled. 
64
65
  HANDLE waiters_done_;
66
  // An auto-reset event used by the broadcast/signal thread to wait
67
  // for all the waiting thread(s) to wake up and be released from the
68
  // semaphore. 
69
70
  size_t was_broadcast_;
71
  // Keeps track of whether we were broadcasting or signaling.  This
72
  // allows us to optimize the code if we're just signaling.
73
} pthread_cond_t;
74
#endif
75
76
#define	TC_CREATE_JOINABLE		PTHREAD_CREATE_JOINABLE
77
#define	TC_CREATE_DETACHED		PTHREAD_CREATE_DETACHED
78
#define TC_SCOPE_SYSTEM			PTHREAD_SCOPE_SYSTEM
79
#define TC_SCOPE_PROCESS		PTHREAD_SCOPE_PROCESS
80
#define TC_PROCESS_PRIVATE		PTHREAD_PROCESS_PRIVATE
81
#define TC_PROCESS_SHARED		PTHREAD_PROCESS_SHARED
82
83
#define TC_MUTEX_INITIALIZER		{ .mut = PTHREAD_MUTEX_INITIALIZER }
84
#define TC_RWLOCK_INITIALIZER		{ .rwlock = PTHREAD_RWLOCK_INITIALIZER }
85
#define TC_COND_INITIALIZER		{ .cond = PTHREAD_COND_INITIALIZER }
86
#define TC_SPIN_INITIALIZER		{ .spin = 0 }
87
88
#if defined(PTHREAD_MUTEX_ERRORCHECK)
89
#define	TC_MUTEX_ERRORCHECK		PTHREAD_MUTEX_ERRORCHECK
90
#else
91
#define	TC_MUTEX_ERRORCHECK		PTHREAD_MUTEX_ERRORCHECK_NP
92
#endif
93
#define	TC_MUTEX_RECURSIVE		PTHREAD_MUTEX_RECURSIVE
94
#define	TC_MUTEX_NORMAL			PTHREAD_MUTEX_NORMAL
95
#define	TC_MUTEX_DEFAULT		PTHREAD_MUTEX_DEFAULT
96
97
98
typedef	tbus				tc_thread_t;
99
typedef	sem_t				tc_sem_t;
100
typedef	pthread_attr_t			tc_threadattr_t;
101
typedef	pthread_mutex_t			tc_mut_t;
102
typedef	pthread_mutexattr_t		tc_mutattr_t;
103
typedef	pthread_cond_t			tc_cond_t;
104
typedef	pthread_condattr_t		tc_condattr_t;
105
typedef	pthread_rwlock_t		tc_rwlock_t;
106
typedef	pthread_rwlockattr_t		tc_rwlockattr_t;
107
typedef	pthread_key_t			tc_key_t;
108
typedef struct timespec			tc_datetime_t;
109
typedef int				tc_future_t;
110
111
#ifdef __USE_XOPEN2K
112
typedef	pthread_barrier_t		tc_barr_t;
113
typedef	pthread_barrierattr_t		tc_barrattr_t;
114
typedef	pthread_spinlock_t		tc_spin_t;
115
#endif
116
117
#define	TC_THREAD_T			tbus
118
#define	TC_SEM_T			sem_t
119
#define	TC_THREADATTR_T			pthread_attr_t
120
#define	TC_MUT_T			pthread_mutex_t
121
#define	TC_MUTATTR_T			pthread_mutexattr_t
122
#define	TC_COND_T			pthread_cond_t
123
#define	TC_CONDATTR_T			pthread_condattr_t
124
#define	TC_RWLOCK_T			pthread_rwlock_t
125
#define	TC_RWLOCKATTR_T			pthread_rwlockattr_t
126
#define	TC_KEY_T			pthread_key_t
127
128
#ifdef __USE_XOPEN2K
129
#define TC_BARR_T			pthread_barrier_t
130
#define TC_BARRATTR_T			pthread_barrierattr_t
131
#define TC_SPIN_T			pthread_spinlock_t
132
#endif
133
134
typedef struct tc_val {
135
	#define	TC_RETVAL_MAGIC		0xacedf001
136
	uint32_t			magic;
137
	tc_thread_t			thread;
138
	unsigned long			len;
139
	uint8_t				data[];
140
} tc_retval_t, *tc_retval_p, tc_args_t, *tc_args_p, tc_val, *tc_val_p;
141
142
typedef union tc_union {
143
	tc_sem_t			sem;
144
	tc_thread_t			thread;
145
	tc_threadattr_t			threadattr;
146
	tc_mut_t			mut;
147
	tc_mutattr_t			mutattr;
148
	tc_cond_t			cond;
149
	tc_condattr_t			condattr;
150
	tc_rwlock_t			rwlock;
151
	tc_rwlockattr_t			rwlockattr;
152
	tc_key_t			key;
153
	tc_retval_t			retval;
154
#ifdef __USE_XOPEN2K
155
	tc_barr_t			barrier;
156
	tc_barrattr_t			barrattr;
157
	tc_spin_t			spin;
158
#endif
159
} tc_t, *tc_p;
160
161
162
163
tc_thread_t APP_CC
32
tc_thread_create(THREAD_RV (THREAD_CC * start_routine)(void*), void* arg);
164
tc_thread_create(THREAD_RV (THREAD_CC * start_routine)(void*), void* arg);
33
tbus APP_CC
165
int APP_CC
166
tc_thread_init_full(tc_thread_t *, const tc_threadattr_t *, void * (* start_routine)(void *), void *);
167
int APP_CC
168
tc_thread_init(tc_thread_t *, THREAD_RV (THREAD_CC * start_routine)(void*), void *);
169
int APP_CC
170
tc_thread_join(tc_thread_t, void **);
171
int APP_CC
172
tc_thread_detach(tc_thread_t);
173
void APP_CC
174
tc_thread_exit(void *);
175
int APP_CC
176
tc_thread_signal(tc_thread_t, int);
177
tc_thread_t APP_CC
34
tc_get_threadid(void);
178
tc_get_threadid(void);
35
int APP_CC
179
int APP_CC
36
tc_threadid_equal(tbus tid1, tbus tid2);
180
tc_threadid_equal(tc_thread_t, tc_thread_t);
37
tbus APP_CC
181
tc_p APP_CC
38
tc_mutex_create(void);
182
tc_mutex_create(void);
39
void APP_CC
40
tc_mutex_delete(tbus mutex);
41
int APP_CC
183
int APP_CC
42
tc_mutex_lock(tbus mutex);
184
tc_mutex_init(tc_p, tc_p);			/*	(tc_mut_t *, tc_mutattr_t *)	*/
185
int APP_CC
186
tc_mutex_delete(tc_p mutex);
187
int APP_CC
188
tc_mutex_deinit(tc_p mutex);
43
int APP_CC
189
int APP_CC
44
tc_mutex_unlock(tbus mutex);
190
tc_mutex_lock(tc_p mutex);
45
tbus APP_CC
191
int APP_CC
192
tc_mutex_unlock(tc_p mutex);
193
int APP_CC
194
tc_mutex_timedlock(tc_p, const struct timespec *);
195
int APP_CC
196
tc_mutexattr_init(tc_p);
197
int APP_CC
198
tc_mutexattr_destroy(tc_p);
199
int APP_CC
200
tc_mutexattr_gettype(tc_p);
201
int APP_CC
202
tc_mutexattr_getprotocol(tc_p);
203
int APP_CC
204
tc_mutexattr_getpshared(tc_p);
205
int APP_CC
206
tc_mutexattr_settype(tc_p, int);
207
int APP_CC
208
tc_mutexattr_setprotocol(tc_p, int);
209
int APP_CC
210
tc_mutexattr_setpshared(tc_p, int);
211
tc_p APP_CC
46
tc_sem_create(int init_count);
212
tc_sem_create(int init_count);
47
void APP_CC
213
void APP_CC
48
tc_sem_delete(tbus sem);
214
tc_sem_delete(tc_p sem);
215
void APP_CC
216
tc_sem_deinit(tc_p sem);
49
int APP_CC
217
int APP_CC
50
tc_sem_dec(tbus sem);
218
tc_sem_dec(tc_p sem);
51
int APP_CC
219
int APP_CC
52
tc_sem_inc(tbus sem);
220
tc_sem_inc(tc_p sem);
221
int APP_CC
222
tc_cond_create(tc_p, const tc_p);	/*	(tc_cond_t *, tc_condattr_t *)	*/
223
int APP_CC
224
tc_cond_wait(tc_p, tc_p);		/*	(tc_cond_t *, tc_mutex_t *)	*/
225
int APP_CC
226
tc_cond_timedwait(tc_p, tc_p, tc_future_t);	/*	(tc_cond_t *, tc_mutex_t *, tc_future_t)	*/
227
int APP_CC
228
tc_cond_signal(tc_p);
229
int APP_CC
230
tc_cond_broadcast(tc_p);
231
int APP_CC
232
tc_cond_delete(tc_p);
233
int APP_CC
234
tc_cond_deinit(tc_p);
235
236
int APP_CC
237
tc_condattr_init(tc_p);
238
int APP_CC
239
tc_condattr_deinit(tc_p);
240
int APP_CC
241
tc_condattr_getpshared(const tc_p, int *);
242
int APP_CC
243
tc_condattr_setpshared(tc_p, int);
244
245
int APP_CC
246
tc_spin_init(tc_p);
247
int APP_CC
248
tc_spin_destroy(tc_p);
249
int APP_CC
250
tc_spin_deinit(tc_p);
251
int APP_CC
252
tc_spin_lock(tc_p);
253
int APP_CC
254
tc_spin_unlock(tc_p);
255
int APP_CC
256
tc_spin_trylock(tc_p);
257
258
int APP_CC
259
tc_barrattr_init(tc_p);
260
int APP_CC
261
tc_barrattr_setpshared(tc_p, int);
262
int APP_CC
263
tc_barrier_init(tc_p, int);
264
int APP_CC
265
tc_barrier_init_full(tc_p, tc_p, int);
266
int APP_CC
267
tc_barrier_deinit(tc_p);
268
int APP_CC
269
tc_barrier_wait(tc_p);
270
271
int APP_CC
272
tc_threadattr_init(tc_p);
273
int APP_CC
274
tc_threadattr_getdetachstate(const tc_p, int *);
275
int APP_CC
276
tc_threadattr_setdetachstate(tc_p, int);
277
int APP_CC
278
tc_threadattr_getscope(const tc_p, int *);
279
int APP_CC
280
tc_threadattr_setscope(tc_p, int);
281
int APP_CC
282
tc_threadattr_setstacksize(tc_p, size_t);
283
int APP_CC
284
tc_threadattr_getstacksize(tc_p, size_t *);
285
286
int APP_CC
287
tc_mutattr_init(tc_p);
288
int APP_CC
289
tc_mutattr_settype(tc_p, int);
290
int APP_CC
291
tc_mutattr_gettype(tc_p attr);
292
int APP_CC
293
tc_mutattr_setpshared(tc_p, int);
294
int APP_CC
295
tc_mutattr_getpshared(const tc_p, int *);
296
int APP_CC
297
tc_mutattr_setprotocol(tc_p, int);
298
int APP_CC
299
tc_mutattr_getprotocol(tc_p);
300
int APP_CC
301
tc_mutattr_destroy(tc_p);
302
303
int APP_CC tc_mutex_trylock(tc_p);
304
305
void * t_malloc(void *, size_t, unsigned char);
306
void t_free(void *, void *);
307
53
308
54
#endif
309
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/thread_macros.h (+190 lines)
Line 0    Link Here 
1
#include "thread_calls.h"
2
3
#ifndef __XRDP_TC_MACROS__
4
#define __XRDP_TC_MACROS__
5
6
//# d efine DISABLE_THREADS_
7
//# d efine ENABLE_SPINLOCKS_
8
//# d efine DEBUG_THREADS_
9
10
#if defined(DISABLE_THREADS)
11
  #define TC_THREAD_CREATE(x,y,z)	;
12
  #define TC_THREAD_INIT(x,y,z)		;
13
  #define TC_THREAD_INIT_FULL(w,x,y,z)	;
14
  #define TC_THREAD_JOIN(x)		;
15
  #define TC_THREADATTR_INIT(x)		;
16
  #define TC_THREADATTR_SETDETACHSTATE(x,y)	;
17
  #define TC_THREADATTR_SETPSHARED(x,y)	;
18
  #define TC_THREADATTR_SETSTACKSIZE(x,y)	;
19
  #define TC_THREADATTR_GETSTACKSIZE(x,y)	;
20
  #define TC_THREADATTR_DEINIT(x)	;
21
  #define TC_MUTEX_INIT(x, y)		;
22
  #define TC_MUTEX_DEINIT(x)		;
23
  #define TC_MUTEX_LOCK(x)		;
24
  #define TC_MUTEX_UNLOCK(x)		;
25
  #define TC_MUTEX_TRYLOCK(x)		;
26
  #define TC_MUTEX_TIMEDLOCK(x, y)	;
27
  #define TC_SPIN_INIT(x)		;
28
  #define TC_SPIN_DEINIT(x)		;
29
  #define TC_SPIN_LOCK(x)		;
30
  #define TC_SPIN_UNLOCK(x)		;
31
  #define TC_COND_CREATE(x, y)		;
32
  #define TC_COND_WAIT(x, y)		;
33
  #define TC_COND_TIMEDWAIT(x, y, z)	;
34
  #define TC_COND_SIGNAL(x)		;
35
  #define TC_COND_BROADCAST(x)		;
36
  #define TC_COND_DELETE(x)		;
37
  #define TC_COND_DEINIT(x)		;
38
  #define TC_BARRATTR_INIT(x)		;
39
  #define TC_BARRATTR_SETPSHARED(x,y)	;
40
  #define TC_BARR_INIT(x,y)		;
41
  #define TC_BARR_DEINIT(x)		;
42
  #define TC_BARR_WAIT(x)		;
43
  #define TC_THREAD_EXIT(x)		;
44
  #define TC_THREAD_KILL(x)		;
45
#else
46
  #if defined(ENABLE_SPINLOCKS)
47
    #define TC_THREAD_CREATE(x,y,z)	tc_thread_init(x,y,z)
48
    #define TC_THREAD_INIT(x,y,z)	tc_thread_init(x,y,z)
49
    #define TC_THREAD_INIT_FULL(w,x,y,z)	tc_thread_init_full(w,x,y,z)
50
    #define TC_THREAD_EXIT(x)		tc_thread_exit((tc_p)x)
51
    #define TC_THREAD_JOIN(x)		tc_thread_join(x)
52
    #define TC_THREAD_KILL(x)		tc_thread_signal(x,SIGTERM)
53
    #define TC_THREADATTR_INIT(x)	tc_threadattr_init(x)
54
    #define TC_THREADATTR_SETDETACHSTATE(x,y)	tc_threadattr_setdetachstate(x,y)
55
    #define TC_THREADATTR_SETPSHARED(x,y)	tc_threadattr_setpshared(x,y)
56
    #define TC_THREADATTR_SETSTACKSIZE(x,y)	tc_threadattr_setstacksize(x,y);
57
    #define TC_THREADATTR_GETSTACKSIZE(x,y)	tc_threadattr_getstacksize(x,y);
58
    #define TC_THREADATTR_DEINIT(x)	tc_threadattr_deinit(x)
59
    #define TC_MUTEX_INIT(x, y)		tc_spin_init((tc_p)x)
60
    #define TC_MUTEX_LOCK(x)		tc_spin_lock((tc_p)x)
61
    #define TC_MUTEX_UNLOCK(x)		tc_spin_unlock((tc_p)x)
62
    #define TC_MUTEX_DEINIT(x)		tc_spin_destroy((tc_p)x)
63
    #define TC_MUTEX_TRYLOCK(x)		tc_spin_trylock((tc_p)x)
64
    #define TC_MUTEX_TIMEDLOCK(x)	tc_spin_timedlock((tc_p)x)
65
    #define TC_COND_CREATE(x, y)	tc_cond_create((tc_p)x, y)
66
    #define TC_COND_WAIT(x, y)		tc_cond_wait((tc_p)x, y)
67
    #define TC_COND_TIMEDWAIT(x, y, z)	tc_cond_timedwait((tc_p)x, y, z)
68
    #define TC_COND_SIGNAL(x)		tc_cond_signal((tc_p)x)
69
    #define TC_COND_BROADCAST(x)	tc_cond_broadcast((tc_p)x)
70
    #define TC_COND_DELETE(x)		tc_cond_delete((tc_p)x)
71
    #define TC_COND_DEINIT(x)		tc_cond_deinit((tc_p)x)
72
#if defined(__USE_XOPEN2K)
73
    #define TC_BARRATTR_INIT(x)		tc_barrattr_init((tc_p)x)
74
    #define TC_BARRATTR_SETPSHARED(x,y)	tc_barrattr_setpshared((tc_p)x, y)
75
    #define TC_BARR_INIT(x,y)		tc_barrier_init((tc_p)x, y)
76
    #define TC_BARR_INIT_FULL(x,y,z)	tc_barrier_init_full((tc_p)x, (tc_p)y, z)
77
    #define TC_BARR_DEINIT(x)		tc_barrier_deinit((tc_p)x)
78
    #define TC_BARR_WAIT(x)		tc_barrier_wait((tc_p)x)
79
    #define TC_SPIN_INIT(x)		tc_spin_init(x)
80
    #define TC_SPIN_DEINIT(x)		tc_spin_deinit(x)
81
    #define TC_SPIN_LOCK(x)		tc_spin_lock(x)
82
    #define TC_SPIN_UNLOCK(x)		tc_spin_unlock(x)
83
#else
84
    #define TC_BARR_INIT(x,y)		0
85
    #define TC_BARR_INIT_FULL(x,y,z)	0
86
    #define TC_BARR_DEINIT(x)		0
87
    #define TC_BARR_WAIT(x)		0
88
    #define TC_SPIN_INIT(x)		0
89
    #define TC_SPIN_DEINIT(x)		0
90
    #define TC_SPIN_LOCK(x)		0
91
    #define TC_SPIN_UNLOCK(x)		0
92
#endif
93
  #else
94
    #define TC_THREAD_CREATE(x,y,z)	tc_thread_init(x,y,z)
95
    #define TC_THREAD_INIT(x,y,z)	tc_thread_init(x,y,z)
96
    #define TC_THREAD_INIT_FULL(w,x,y,z)	tc_thread_init_full(w,x,y,z)
97
    #define TC_THREAD_EXIT(x)		tc_thread_exit((tc_p)x)
98
    #define TC_THREAD_JOIN(x,y)		tc_thread_join(x,y)
99
    #define TC_THREAD_KILL(x)		tc_thread_signal(x,SIGTERM)
100
    #define TC_THREADATTR_INIT(x)	tc_threadattr_init(x)
101
    #define TC_THREADATTR_SETDETACHSTATE(x,y)	tc_threadattr_setdetachstate(x,y)
102
    #define TC_THREADATTR_SETPSHARED(x,y)	tc_threadattr_setpshared(x,y)
103
    #define TC_THREADATTR_SETSTACKSIZE(x,y)	tc_threadattr_setstacksize(x,y);
104
    #define TC_THREADATTR_GETSTACKSIZE(x,y)	tc_threadattr_getstacksize(x,y);
105
    #define TC_THREADATTR_DEINIT(x)	tc_threadattr_deinit(x)
106
    #define TC_MUTEX_INIT(x, y)		tc_mutex_init((tc_p)x, (tc_p)y)
107
    #define TC_MUTEX_LOCK(x)		if (x != NULL) { tc_mutex_lock((tc_p)x); }
108
    #define TC_MUTEX_UNLOCK(x)		if (x != NULL) { tc_mutex_unlock((tc_p)x); }
109
    #define TC_MUTEX_DEINIT(x)		if (x != NULL) { tc_mutex_deinit((tc_p)x); }
110
    #define TC_MUTEX_TRYLOCK(x)		tc_mutex_trylock((tc_p)x)
111
    #define TC_MUTEX_TIMEDLOCK(x, y)	tc_mutex_timedlock((tc_p)x, (const struct timespec *)y)
112
    #define TC_MUTATTR_INIT(x)		tc_mutattr_init((tc_p)x)
113
    #define TC_MUTATTR_DEINIT(x)	tc_mutattr_destroy((tc_p)x)
114
    #define TC_MUTATTR_GETTYPE(x)	tc_mutattr_gettype((tc_p)x)
115
    #define TC_MUTATTR_GETPROTOCOL(x)	tc_mutattr_getprotocol((tc_p)x)
116
    #define TC_MUTATTR_GETPSHARED(x, y)	tc_mutattr_getpshared((const tc_p)x, (int *)y)
117
    #define TC_MUTATTR_SETTYPE(x, y)	tc_mutattr_settype((tc_p)x, (int)y)
118
    #define TC_MUTATTR_SETPROTOCOL(x, y)	tc_mutattr_setprotocol((tc_p)x, (int)y)
119
    #define TC_MUTATTR_SETPSHARED(x, y)	tc_mutattr_setpshared((const tc_p)x, (int)y)
120
    #define TC_SPIN_INIT(x)		TC_MUTEX_INIT(x,NULL)
121
    #define TC_SPIN_DEINIT(x)		TC_MUTEX_DEINIT(x)
122
    #define TC_SPIN_LOCK(x)		TC_MUTEX_LOCK(x)
123
    #define TC_SPIN_UNLOCK(x)		TC_MUTEX_UNLOCK(x)
124
    #define TC_CONDATTR_INIT(x)		tc_condattr_init((tc_p)x)
125
    #define TC_CONDATTR_DEINIT(x)	tc_condattr_destroy((tc_p)x)
126
    #define TC_CONDATTR_GETPSHARED(x, y)	tc_condattr_getpshared((const tc_p)x, (int *)y)
127
    #define TC_CONDATTR_SETPSHARED(x, y)	tc_condattr_setpshared((const tc_p)x, (int)y)
128
    #define TC_COND_CREATE(x, y)	tc_cond_create((tc_p)x, y)
129
    #define TC_COND_WAIT(x, y)		tc_cond_wait((tc_p)x, y)
130
    #define TC_COND_TIMEDWAIT(x, y, z)	tc_cond_timedwait((tc_p)x, y, z)
131
    #define TC_COND_SIGNAL(x)		tc_cond_signal((tc_p)x)
132
    #define TC_COND_BROADCAST(x)	tc_cond_broadcast((tc_p)x)
133
    #define TC_COND_DELETE(x)		tc_cond_delete((tc_p)x)
134
    #define TC_COND_DEINIT(x)		tc_cond_deinit((tc_p)x)
135
#if defined(__USE_XOPEN2K)
136
    #define TC_BARRATTR_INIT(x)		tc_barrattr_init((tc_p)x)
137
    #define TC_BARRATTR_SETPSHARED(x,y)	tc_barrattr_setpshared((tc_p)x, y)
138
    #define TC_BARR_INIT(x,y)		tc_barrier_init((tc_p)x, y)
139
    #define TC_BARR_INIT_FULL(x,y,z)	tc_barrier_init_full((tc_p)x, (tc_p)y, z)
140
    #define TC_BARR_DEINIT(x)		tc_barrier_deinit((tc_p)x)
141
    #define TC_BARR_WAIT(x)		tc_barrier_wait((tc_p)x)
142
#else
143
    #define TC_BARR_INIT(x,y)		0
144
    #define TC_BARR_INIT_FULL(x,y,z)	0
145
    #define TC_BARR_DEINIT(x)		0
146
    #define TC_BARR_WAIT(x)		0
147
    #define TC_SPIN_INIT(x)		0
148
    #define TC_SPIN_DEINIT(x)		0
149
    #define TC_SPIN_LOCK(x)		0
150
    #define TC_SPIN_UNLOCK(x)		0
151
#endif
152
  #endif
153
154
  #if defined(DEBUG_THREADS)
155
    #undef TC_MUTEX_LOCK
156
    #undef TC_MUTEX_UNLOCK
157
    #undef TC_MUTEX_TRYLOCK
158
    #undef TC_MUTEX_TIMEDLOCK
159
    #define TC_MUTEX_LOCK(x)		;
160
    #define TC_MUTEX_UNLOCK(x)		;
161
    #define TC_MUTEX_TRYLOCK(x)		;
162
    #define TC_MUTEX_TIMEDLOCK(x, y)	;
163
    /*
164
    #define TC_THREAD_CREATE(x,y,z)	tc_thread_init(x,y,z)
165
    #define TC_THREAD_INIT(x,y,z)	tc_thread_init(x,y,z)
166
    #define TC_THREAD_INIT_FULL(w,x,y,z)	tc_thread_init_full(w,x,y,z)
167
    #define TC_MUTEX_LOCK(x)		pthread_mutex_lock(x)
168
    #define TC_MUTEX_UNLOCK(x)		pthread_mutex_unlock(x)
169
    #define TC_MUTEX_TRYLOCK(x)		pthread_mutex_trylock(x)
170
    #define TC_MUTEX_TIMEDLOCK(x, y)	pthread_mutex_timedlock(x, y)
171
    */
172
  #endif
173
174
#endif
175
176
#if defined(__linux__)
177
#if defined(ARM)
178
typedef void (__kernel_dmb_t) (void);
179
#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
180
#define MEM_BARRIER __kernel_dmb()
181
#else
182
#define MEM_BARRIER __sync_synchronize()
183
#endif
184
#else
185
#define	MEM_BARRIER {}
186
#endif
187
#define MB MEM_BARRIER
188
189
190
#endif	/* __XRDP_TC_MACROS__ */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/trans.c (-130 / +573 lines)
 Lines 23-71    Link Here 
23
23
24
*/
24
*/
25
25
26
#include <time.h>
27
#include <netdb.h>
28
#include <fcntl.h>
29
#include <stdio.h>
30
#include <unistd.h>
26
#include "os_calls.h"
31
#include "os_calls.h"
27
#include "trans.h"
32
#include "trans.h"
28
#include "arch.h"
33
#include "arch.h"
29
#include "parse.h"
34
#include "parse.h"
35
#include "dbg.h"
30
36
31
/*****************************************************************************/
37
#if defined(__XRDP_TRANS_LOCKS__)
32
struct trans* APP_CC
38
#undef __XRDP_TRANS_LOCKS__
33
trans_create(int mode, int in_size, int out_size)
39
#endif
34
{
40
35
  struct trans* self;
41
#if 0
42
#if defined(MDBGLOG)
43
#undef MDBGLOG
44
#define MDBGLOG(...)    ;
45
#endif
46
#endif
36
47
37
  self = (struct trans*)g_malloc(sizeof(struct trans), 1);
48
38
  make_stream(self->in_s);
49
/*****************************************************************************/
39
  init_stream(self->in_s, in_size);
50
struct trans * APP_CC
40
  make_stream(self->out_s);
51
trans_create(int mode, size_t in_size, size_t out_size) {
41
  init_stream(self->out_s, out_size);
52
  struct trans * self = (struct trans *)NULL;
42
  self->mode = mode;
53
54
  // MDBGLOG("trans","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
55
56
  self = (struct trans *)g_malloc(sizeof(struct trans), 1);
57
  if (self != NULL) {
58
	make_stream(self->in_s);
59
	init_stream(self->in_s, in_size);
60
	make_stream(self->out_s);
61
	init_stream(self->out_s, out_size);
62
	self->mode = mode;
63
  }
43
  return self;
64
  return self;
44
}
65
}
45
66
46
/*****************************************************************************/
67
/*****************************************************************************/
47
void APP_CC
68
void APP_CC
48
trans_delete(struct trans* self)
69
trans_delete(struct trans * self) {
49
{
70
  // MDBGLOG("trans","INFO\t[%s()]: called (self = %p) [%d, %d]",__func__,self,g_getpid(),g_gettid());
50
  if (self == 0)
71
  if (self == 0) {
51
  {
72
    // MDBGLOG("trans","WARNING\t[%s()]: self is NULL",__func__);
52
    return;
73
    return;
53
  }
74
  }
54
  free_stream(self->in_s);
75
  free_stream(self->in_s);
55
  free_stream(self->out_s);
76
  free_stream(self->out_s);
56
  g_tcp_close(self->sck);
77
  if (self->sck > 0) {
78
    g_tcp_close(self->sck);
79
  }
80
  self->sck = 0;
57
  if (self->listen_filename != 0)
81
  if (self->listen_filename != 0)
58
  {
82
  {
59
    g_file_delete(self->listen_filename);
83
    g_file_delete(self->listen_filename);
60
    g_free(self->listen_filename);
84
    g_free(self->listen_filename);
61
  }
85
  }
62
  g_free(self);
86
  // MDBGLOG("trans","INFO\t[%s()]: done.",__func__);
63
}
87
}
64
88
65
/*****************************************************************************/
89
/*****************************************************************************/
66
int APP_CC
90
int APP_CC
67
trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout)
91
trans_get_wait_objs(struct trans * self, tbus objs[], ptrdiff_t * count, int * timeout) {
68
{
92
  // MDBGLOG("trans","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
93
69
  if (self == 0)
94
  if (self == 0)
70
  {
95
  {
71
    return 1;
96
    return 1;
 Lines 74-125    Link Here 
74
  {
99
  {
75
    return 1;
100
    return 1;
76
  }
101
  }
77
  objs[*count] = self->sck;
102
  objs[(*count)] = self->sck;
78
  (*count)++;
103
  (*count)++;
104
  if (0 && (self->mode == 0 || self->mode == 3) && self->sck_out > 0) {
105
    objs[(*count)] = self->sck_out;
106
    (*count)++;
107
  }
108
109
  // MDBGLOG("trans","INFO\t[%s()]: done.",__func__);
110
79
  return 0;
111
  return 0;
80
}
112
}
81
113
82
/*****************************************************************************/
114
/*****************************************************************************/
83
int APP_CC
115
int APP_CC
84
trans_check_wait_objs(struct trans* self)
116
trans_check_wait_objs(struct trans * self) {
85
{
117
  tbus in_sck = (tbus)0;
86
  tbus in_sck;
118
  struct trans* in_trans = (struct trans *)NULL;
87
  struct trans* in_trans;
119
  ptrdiff_t read_bytes = 0;
88
  int read_bytes;
120
  ptrdiff_t to_read = 0;
89
  int to_read;
121
  ptrdiff_t read_so_far = 0;
90
  int read_so_far;
122
  int rv = 0;
91
  int rv;
123
  int tmp = 0;
92
124
93
  if (self == 0)
125
  if (self == 0)
94
  {
126
  {
95
    return 1;
127
    MDBGLOG("chansrv","ERROR\t[%s()]: self == 0",__func__);
128
    rv = 1;
129
    goto end;
96
  }
130
  }
97
  if (self->status != 1)
131
  if (self->status != 1)
98
  {
132
  {
99
    return 1;
133
    // MDBGLOG("chansrv","ERROR\t[%s()]: self->status is not equal to 1",__func__);
134
    rv = 1;
135
    goto end;
100
  }
136
  }
101
  rv = 0;
137
  rv = 0;
102
  if (self->type1 == 1) /* listening */
138
  if (self->type1 == 1) /* listening */
103
  {
139
  {
104
    if (g_tcp_can_recv(self->sck, 0))
140
    if ((self->mode == 0 || self->mode == 3) && g_fifo_can_read(self->sck, 0)) {
141
      in_sck = self->sck;
142
      if (in_sck == -1) {
143
      }
144
      else {
145
        if (self->trans_conn_in != NULL) { /* is function assigned */
146
          in_trans = trans_create(self->mode, self->in_s->size,
147
                                  self->out_s->size);
148
          in_trans->sck = in_sck;
149
          in_trans->type1 = 2;
150
          in_trans->status = 1;
151
          if (self->trans_conn_in(self, in_trans) != 0)
152
          {
153
            trans_delete(in_trans);
154
          }
155
        }
156
        else {
157
          g_tcp_close(in_sck);
158
        }
159
      }
160
    }
161
    else if ((self->mode == 1 || self->mode == 2) && g_tcp_can_recv(self->sck, 0))
105
    {
162
    {
106
      in_sck = g_tcp_accept(self->sck);
163
      in_sck = g_tcp_accept(self->sck);
107
      if (in_sck == -1)
164
      if (in_sck == -1)
108
      {
165
      {
166
	// MDBGLOG("chansrv","INFO\t[%s()]: g_tcp_accept() returned -1",__func__);
109
        if (g_tcp_last_error_would_block(self->sck))
167
        if (g_tcp_last_error_would_block(self->sck))
110
        {
168
        {
111
          /* ok, but shouldn't happen */
169
          /* ok, but shouldn't happen */
170
	  // MDBGLOG("chansrv","INFO\t[%s()]: last error would block (\"ok, but shouldn't happen\")",__func__);
112
        }
171
        }
113
        else
172
        else
114
        {
173
        {
115
          /* error */
174
          /* error */
116
          self->status = 0;
175
          self->status = 0;
117
          rv = 1;
176
          rv = 1;
177
	  MDBGLOG("chansrv","ERROR\t[%s()]: g_tcp_last_error_would_block(self->sck)",__func__);
118
        }
178
        }
119
      }
179
      }
120
      if (in_sck != -1)
180
      if (in_sck != -1)
121
      {
181
      {
122
        if (self->trans_conn_in != 0) /* is function assigned */
182
        if (self->trans_conn_in != NULL) /* is function assigned */
123
        {
183
        {
124
          in_trans = trans_create(self->mode, self->in_s->size,
184
          in_trans = trans_create(self->mode, self->in_s->size,
125
                                  self->out_s->size);
185
                                  self->out_s->size);
 Lines 140-203    Link Here 
140
  }
200
  }
141
  else /* connected server or client (2 or 3) */
201
  else /* connected server or client (2 or 3) */
142
  {
202
  {
143
    if (g_tcp_can_recv(self->sck, 0))
203
    if (self->mode == 0) {
204
      tmp = g_fifo_can_read(self->sck, 0);
205
    }
206
    if (self->mode == 3) {
207
      tmp = g_fifo_can_read(self->sck, 0);
208
    }
209
    else {
210
      tmp = g_tcp_can_recv(self->sck, 0);
211
    }
212
    if (tmp > 0)
144
    {
213
    {
145
      read_so_far = (int)(self->in_s->end - self->in_s->data);
214
      read_so_far = self->in_s->end - self->in_s->data;
146
      to_read = self->header_size - read_so_far;
215
      to_read = self->header_size - read_so_far;
147
      read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0);
216
      if (self->mode == 3 || self->mode == 0) {
217
	if (to_read > 0) {
218
	  read_bytes = g_fifo_read(self->sck, self->in_s->end, to_read);
219
	}
220
	else {
221
	  read_bytes = 0;
222
	}
223
      }
224
      else if (to_read > 0) {
225
	read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0);
226
      }
227
      else {
228
	read_bytes = 0;
229
      }
148
      if (read_bytes == -1)
230
      if (read_bytes == -1)
149
      {
231
      {
232
	// MDBGLOG("chansrv","INFO\t[%s()]: read_bytes = -1",__func__);
150
        if (g_tcp_last_error_would_block(self->sck))
233
        if (g_tcp_last_error_would_block(self->sck))
151
        {
234
        {
152
          /* ok, but shouldn't happen */
235
          /* ok, but shouldn't happen */
236
	  // MDBGLOG("chansrv","INFO\t[%s()]: g_tcp_last_error_would_block() returned -1 (\"ok, but shouldn't happen\")",__func__);
153
        }
237
        }
154
        else
238
        else
155
        {
239
        {
156
          /* error */
240
          /* error */
157
          self->status = 0;
241
          self->status = 0;
158
          rv = 1;
242
          rv = 1;
243
	  MDBGLOG("chansrv","ERROR\t[%s()]: read_bytes == -1 and g_tcp_last_error_would_block(self->sck) is false",__func__);
159
        }
244
        }
160
      }
245
      }
161
      else if (read_bytes == 0)
246
      else if (read_bytes == 0 && self->header_size > 0) {
162
      {
247
	/* error */
163
        /* error */
248
	self->status = 0;
164
        self->status = 0;
249
	rv = 1;
165
        rv = 1;
250
	MDBGLOG("chansrv","ERROR\t[%s()]: read_bytes == 0 and self->header_size > 0",__func__);
166
      }
251
      }
167
      else
252
      else {
168
      {
253
	self->in_s->end += read_bytes;
169
        self->in_s->end += read_bytes;
170
      }
254
      }
171
      read_so_far = (int)(self->in_s->end - self->in_s->data);
255
      read_so_far = (int)(self->in_s->end - self->in_s->data);
172
      if (read_so_far == self->header_size)
256
      if (read_so_far == self->header_size && self->trans_data_in != NULL) {
173
      {
257
	rv = self->trans_data_in(self);
174
        if (self->trans_data_in != 0)
258
	init_stream(self->in_s, 0);
175
        {
176
          rv = self->trans_data_in(self);
177
          init_stream(self->in_s, 0);
178
        }
179
      }
259
      }
180
    }
260
    }
181
  }
261
  }
262
 end:;
263
  if (rv != 0) {
264
    // MDBGLOG("chansrv","ERROR\t[%s()]: rv = %d",__func__,rv);
265
  }
182
  return rv;
266
  return rv;
183
}
267
}
184
268
185
/*****************************************************************************/
269
/*****************************************************************************/
186
int APP_CC
270
ptrdiff_t APP_CC
187
trans_force_read(struct trans* self, int size)
271
trans_force_read(struct trans* self, size_t size)
188
{
272
{
189
  int rv;
273
  ptrdiff_t rv = 0;
190
  int rcvd;
274
  ptrdiff_t rcvd = 0;
275
  time_t start_timestamp = 0;
276
  time_t current_timestamp = 0;
277
  time_t previous_timestamp = 0;
278
  unsigned int elapsed = 0;  
279
280
  if (self == NULL) {
281
    rv = 1;
282
    goto end;
283
  }
284
285
  start_timestamp = time(NULL);
286
  previous_timestamp = 0;
287
  current_timestamp = start_timestamp;
288
  elapsed = current_timestamp - start_timestamp;
191
289
290
  rv = 0;
192
  if (self->status != 1)
291
  if (self->status != 1)
193
  {
292
  {
194
    return 1;
293
    rv = 1;
195
  }
294
  }
196
  rv = 0;
295
  else while (size > 0)
197
  while (size > 0)
296
  { 
198
  {
297
    if (self->mode == 0) {
199
    rcvd = g_tcp_recv(self->sck, self->in_s->end, size, 0);
298
      rcvd = g_file_read(self->sck, self->in_s->end, size);
200
    if (rcvd == -1)
299
    }
300
    else if (self->mode == 3) {
301
      rcvd = g_fifo_read(self->sck, self->in_s->end, size);
302
    }
303
    else if (self->mode == 1 || self->mode == 2) {
304
      rcvd = g_tcp_recv(self->sck, self->in_s->end, size, 0);
305
    }
306
    if (rcvd == -1 && self->mode != 3)
201
    {
307
    {
202
      if (g_tcp_last_error_would_block(self->sck))
308
      if (g_tcp_last_error_would_block(self->sck))
203
      {
309
      {
 Lines 224-269    Link Here 
224
      self->in_s->end += rcvd;
330
      self->in_s->end += rcvd;
225
      size -= rcvd;
331
      size -= rcvd;
226
    }
332
    }
333
227
  }
334
  }
335
336
 end:;
228
  return rv;
337
  return rv;
229
}
338
}
230
339
231
/*****************************************************************************/
340
/*****************************************************************************/
232
int APP_CC
341
ptrdiff_t APP_CC
233
trans_force_write(struct trans* self)
342
trans_read(struct trans* self, size_t size)
234
{
343
{
235
  int size;
344
  ptrdiff_t rv = 0;
236
  int total;
345
  ptrdiff_t rcvd = 0;
237
  int rv;
346
  int cont = 1;
238
  int sent;
239
347
240
  if (self->status != 1)
348
  // MDBGLOG("trans","INFO\t[%s()]: called (size = %d, self->sck = %d) [%d, %d]",__func__,size,(int)self->sck,g_getpid(),g_gettid());
241
  {
349
242
    return 1;
350
  if (self == NULL) {
351
    rv = -1;
352
    goto end;
243
  }
353
  }
244
  rv = 0;
354
245
  size = (int)(self->out_s->end - self->out_s->data);
355
  if (self->status != 1) {
246
  total = 0;
356
    rv = -2;
247
  while (total < size)
357
    goto end;
248
  {
358
  }
249
    sent = g_tcp_send(self->sck, self->out_s->data + total, size - total, 0);
359
  else while (cont > 0) {
250
    if (sent == -1)
360
    cont = 0;
251
    {
361
    if (self->mode == 0) {
252
      if (g_tcp_last_error_would_block(self->sck))
362
      rcvd = g_file_read(self->sck, self->in_s->end, size);
253
      {
363
    }
254
        if (!g_tcp_can_send(self->sck, 10))
364
    else if (self->mode == 3) {
365
      rcvd = g_fifo_read(self->sck, self->in_s->end, size);
366
    }
367
    else if (self->mode == 1 || self->mode == 2) {
368
      rcvd = g_tcp_recv(self->sck, self->in_s->end, size, 0);
369
    }
370
    if (rcvd == -1 && self->mode != 3 && self->mode != 0) {
371
      if (g_tcp_last_error_would_block(self->sck)) {
372
        if (!g_tcp_can_recv(self->sck, 10))
255
        {
373
        {
256
          /* check for term here */
374
          /* check for term here */
257
        }
375
        }
376
	cont = 1;
258
      }
377
      }
259
      else
378
      else {
260
      {
261
        /* error */
379
        /* error */
262
        self->status = 0;
380
        self->status = 0;
263
        rv = 1;
381
        rv = 1;
264
      }
382
      }
265
    }
383
    }
266
    else if (sent == 0)
384
    else if (rcvd == 0)
267
    {
385
    {
268
      /* error */
386
      /* error */
269
      self->status = 0;
387
      self->status = 0;
 Lines 271-279    Link Here 
271
    }
389
    }
272
    else
390
    else
273
    {
391
    {
274
      total = total + sent;
392
      self->in_s->end += rcvd;
393
      size -= rcvd;
394
    }
395
    if (size < 1 ) {
396
      cont = 0;
275
    }
397
    }
276
  }
398
  }
399
  rv = (rcvd > -1) ? (size_t)(rcvd) : 0;
400
401
 end:;
402
  // MDBGLOG("trans","INFO\t[%s()]: done (read %d bytes).", __func__, rv);
403
  return rv;
404
}
405
406
/*****************************************************************************/
407
ptrdiff_t APP_CC
408
trans_force_write(struct trans* self) {
409
  ptrdiff_t size = 0;
410
  ptrdiff_t total = 0;
411
  ptrdiff_t rv = 0;
412
  ptrdiff_t sent = 0;
413
  time_t start_timestamp = 0;
414
  time_t current_timestamp = 0;
415
  time_t previous_timestamp = 0;
416
  unsigned int elapsed = 0;
417
418
  if (self == NULL || self->sck < 1) {
419
    rv = -1;
420
    MDBGLOG("chansrv","ERROR\t[%s() @ line %d]: not ready",__func__,__LINE__);
421
    goto end;
422
  }
423
424
  start_timestamp = time(NULL);
425
  previous_timestamp = 0;
426
  current_timestamp = start_timestamp;
427
  elapsed = current_timestamp - start_timestamp;
428
429
  if (self->status != 1) {
430
    rv = -5;
431
    MDBGLOG("chansrv","ERROR\t[%s() @ line %d]: status is not ready",__func__,__LINE__);
432
    goto end;
433
  }
434
  else {
435
    rv = 0;
436
    size = self->out_s->end - self->out_s->data;
437
    total = 0;
438
    while (total < size) {
439
      sent = 0;
440
      if (self->mode == 0) {
441
	if (self->sck_out != 0) {
442
	  sent = g_file_write(self->sck_out, (self->out_s->data + total), (size - total));
443
	}
444
	else {
445
	  sent = g_file_write(self->sck, (self->out_s->data + total), (size - total));
446
	}
447
      }
448
      else if (self->mode == 3) {
449
	if (self->sck_out != 0) {
450
	  sent = g_fifo_write(self->sck_out, (self->out_s->data + total), (size - total));
451
	}
452
	else {
453
	  sent = g_fifo_write(self->sck, (self->out_s->data + total), (size - total));
454
	}
455
      }
456
      else if ((self->mode == 1 || self->mode == 2) && !g_tcp_socket_ok(self->sck)) {
457
	MDBGLOG("chansrv","WARNING\t[%s()]: self->sck is not OK",__func__);
458
	continue;
459
      }
460
      else if (g_tcp_can_send(self->sck, 50)) {
461
	sent = g_tcp_send_force(self->sck, (self->out_s->data + total), (size - total), self->send_flags);
462
      }
463
      else {
464
	MDBGLOG("chansrv","ERROR\t[%s() @ line %d]: failed",__func__,__LINE__);
465
      }
466
      if (current_timestamp != previous_timestamp) {
467
	// MDBGLOG("trans","INFO\t[%s()]: [%d] total = %d (out of %d); sent = %d; self->sck = %d ...",__func__,elapsed,total,size,sent,self->sck);
468
      }
469
      if (sent == -1) {
470
        if (g_tcp_last_error_would_block(self->sck)) {
471
          if (!g_tcp_can_send(self->sck, 10)) {
472
            /* check for term here */
473
          }
474
        }
475
        else {
476
          /* error */
477
          self->status = 0;
478
          rv = -2;
479
	  MDBGLOG("chansrv","ERROR\t[%s() @ line %d]: sent = -1",__func__,__LINE__);
480
        }
481
      }
482
      else if (sent == 0) {
483
        /* error */
484
        self->status = 0;
485
        rv = -3;
486
	MDBGLOG("chansrv","ERROR\t[%s() @ line %d]: sent = 0",__func__,__LINE__);
487
      }
488
      else {
489
        total = total + sent;
490
	if (total >= size) {
491
	  break;
492
	}
493
      }
494
      previous_timestamp = current_timestamp;
495
      current_timestamp = time(NULL);
496
      elapsed = current_timestamp - start_timestamp;
497
    }
498
  }
499
500
  if (elapsed > 4) {
501
    // MDBGLOG("trans","WARNING\t[%s()]: timed out! total = %d",__func__,total);
502
    MDBGLOG("chansrv","WARNING\t[%s() @ line %d]: timed out (total = %d)",__func__,__LINE__,total);
503
    rv = -4;
504
  }
505
506
 end:;
277
  return rv;
507
  return rv;
278
}
508
}
279
509
 Lines 282-308    Link Here 
282
trans_connect(struct trans* self, const char* server, const char* port,
512
trans_connect(struct trans* self, const char* server, const char* port,
283
              int timeout)
513
              int timeout)
284
{
514
{
285
  int error;
515
  int error = 0;
286
516
287
  if (self->sck != 0)
517
  // MDBGLOG("trans","INFO\t[%s()]: called (server = %s; port = %s; timeout = %d; self->mode = %d; self->sck = %d) [%d, %d]",__func__,server,port,timeout,self->mode,self->sck,g_getpid(),g_gettid());
288
  {
518
519
  if (self == NULL) {
520
    return -1;
521
  }
522
523
  if (self->sck != 0 && self->mode == 3) {
524
    g_file_close(self->sck);
525
  }
526
  else if (self->sck != 0 && self->mode != 3) {
289
    g_tcp_close(self->sck);
527
    g_tcp_close(self->sck);
290
  }
528
  }
291
  if (self->mode == 1) /* tcp */
529
  if (self->mode == 0) {	/* stdin/stdout */
292
  {
530
    self->sck = fcntl(STDIN_FILENO, F_DUPFD);
531
    self->sck_out = fcntl(STDOUT_FILENO, F_DUPFD);
532
  }
533
  if (self->mode == 1) {	/* tcp */
293
    self->sck = g_tcp_socket();
534
    self->sck = g_tcp_socket();
294
    g_tcp_set_non_blocking(self->sck);
535
    g_tcp_set_non_blocking(self->sck);
295
    error = g_tcp_connect(self->sck, server, port);
536
    error = g_tcp_connect(self->sck, server, port);
296
  }
537
  }
297
  else if (self->mode == 2) /* unix socket */
538
  else if (self->mode == 2) {	/* unix socket */
298
  {
299
    self->sck = g_tcp_local_socket();
539
    self->sck = g_tcp_local_socket();
300
    g_tcp_set_non_blocking(self->sck);
540
    g_tcp_set_non_blocking(self->sck);
301
    error = g_tcp_local_connect(self->sck, port);
541
    error = g_tcp_local_connect(self->sck, port);
302
  }
542
  }
303
  else
543
  else if (self->mode == 3) {	/* fifo (named pipe) */
304
  {
544
    self->sck = g_fifo_open(server);
545
    //g_fifo_set_blocking(self->sck);
546
  }
547
  else {
305
    self->status = 0;
548
    self->status = 0;
549
    // MDBGLOG("trans","INFO\t[%s()]: done (1).",__func__);
306
    return 1;
550
    return 1;
307
  }
551
  }
308
  if (error == -1)
552
  if (error == -1)
 Lines 311-383    Link Here 
311
    {
555
    {
312
      if (g_tcp_can_send(self->sck, timeout))
556
      if (g_tcp_can_send(self->sck, timeout))
313
      {
557
      {
314
        self->status = 1; /* ok */
558
	self->status = 1; /* ok */
315
        self->type1 = 3; /* client */
559
	self->type1 = 3; /* client */
316
        return 0;
560
	// MDBGLOG("trans","INFO\t[%s()]: done (2).",__func__);
561
	return 0;
317
      }
562
      }
318
    }
563
    }
564
    // MDBGLOG("trans","INFO\t[%s()]: done (3).",__func__);
319
    return 1;
565
    return 1;
320
  }
566
  }
321
  self->status = 1; /* ok */
567
  self->status = 1; /* ok */
322
  self->type1 = 3; /* client */
568
  self->type1 = 3; /* client */
569
570
  // MDBGLOG("trans","INFO\t[%s()]: done (4); error = %d.",__func__,error);
571
323
  return 0;
572
  return 0;
324
}
573
}
325
574
326
/*****************************************************************************/
575
/*****************************************************************************/
327
int APP_CC
576
int APP_CC
328
trans_listen(struct trans* self, char* port)
577
trans_disconnect(struct trans * self) {
329
{
578
330
  if (self->sck != 0)
579
  // MDBGLOG("trans","INFO\t[%s()] called [%d, %d]",__func__,g_getpid(),g_gettid());
331
  {
580
581
  if (self == NULL) {
582
    return -1;
583
  }
584
585
  self->status = 0; /* not connected */
586
  self->type1 = 0;  /* none */
587
  if (self->sck != 0 && (self->mode == 3 || self->mode == 0)) {
588
    g_file_close(self->sck);
589
  }
590
  else if (self->sck != 0 && self->mode != 3) {
332
    g_tcp_close(self->sck);
591
    g_tcp_close(self->sck);
333
  }
592
  }
334
  if (self->mode == 1) /* tcp */
593
594
  return 0;
595
}
596
597
/*****************************************************************************/
598
int APP_CC
599
trans_attach(struct trans * self, int sck) {
600
601
  // MDBGLOG("trans","INFO\t[%s()]: called (sck = %d; self->mode = %d) [%d, %d]",__func__,sck,self->mode,g_getpid(),g_gettid());
602
603
  if (self == NULL) {
604
    // MDBGLOG("trans","ERROR\t[%s()]: invalid socket (sck = %d)",__func__,sck);
605
    return -1;
606
  }
607
608
  if (sck < 1) {
609
    // MDBGLOG("trans","ERROR\t[%s()]: invalid socket (sck = %d)",__func__,sck);
610
    return -1;
611
  }
612
613
  if (self->sck != 0 && (self->mode == 3 || self->mode == 0)) {
614
    g_file_close(self->sck);
615
  }
616
  else if (self->sck != 0) {
617
    g_tcp_close(self->sck);
618
  }
619
  if (self->mode == 1 || self->mode == 2) /* tcp */
620
  {
621
    self->sck = sck;
622
    g_tcp_set_non_blocking(self->sck);
623
  }
624
  else if (self->mode == 3) /* fifo */
335
  {
625
  {
626
    self->sck = sck;
627
    //g_fifo_set_blocking(self->sck);
628
  }
629
  else if (self->mode == 0) /* stdio */
630
  {
631
    self->sck = sck;
632
  }
633
  else {
634
    self->status = 0;
635
    // MDBGLOG("trans","ERROR\t[%s()]: unrecognized self->mode (%d)",__func__,self->mode);
636
    return 1;
637
  }
638
  self->status = 1; /* ok */
639
  self->type1 = 3; /* client */
640
641
  // MDBGLOG("trans","INFO\t[%s()]: done (self->status = %d; self->type1 = %d); error = %d.",__func__,self->status,self->type1);
642
643
  return 0;
644
}
645
646
/*****************************************************************************/
647
int APP_CC
648
trans_detach(struct trans * self) {
649
  int rv = 0;
650
  if (self == NULL) {
651
    rv = -1;
652
  }
653
  else {
654
    if (self->sck != 0 && (self->mode == 3 || self->mode == 0)) {
655
      g_file_close(self->sck);
656
      if (self->sck_out != 0) {
657
	g_file_close(self->sck_out);
658
      }
659
    }
660
    else if (self->sck != 0) {
661
      g_tcp_close(self->sck);
662
    }
663
    self->sck = 0;
664
    self->sck_out = 0;
665
    self->status = 0; /* disconnected */
666
    self->type1 = 0; /* none */
667
  }
668
  return rv;
669
}
670
671
/*****************************************************************************/
672
int APP_CC
673
trans_listen(struct trans* self, char* port) {
674
  int rv = 0;
675
  const int flags = AI_ADDRCONFIG | AI_PASSIVE;
676
677
  // MDBGLOG("trans","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
678
679
  if (self == NULL) {
680
    MDBGLOG("net","ERROR\t[%s()]: self is NULL",__func__);
681
    rv = -1;
682
    goto end;
683
  }
684
  if (self->sck != 0) {
685
    g_tcp_close(self->sck);
686
  }
687
  if (self->mode == 1) { /* tcp */
336
    self->sck = g_tcp_socket();
688
    self->sck = g_tcp_socket();
337
    g_tcp_set_non_blocking(self->sck);
689
    g_tcp_set_non_blocking(self->sck);
338
    if (g_tcp_bind(self->sck, port) == 0)
690
    if (g_tcp_bind_flags(self->sck, port, flags) == 0) {
339
    {
691
        if (g_tcp_listen(self->sck) == 0) {
340
      if (g_tcp_listen(self->sck) == 0)
692
          self->status = 1; /* ok */
341
      {
693
          self->type1 = 1; /* listener */
342
        self->status = 1; /* ok */
694
          rv = 0;
343
        self->type1 = 1; /* listener */
695
	  goto end;
344
        return 0;
696
        }
345
      }
697
	else {
698
	  MDBGLOG("net","ERROR\t[%s()]: g_tcp_listen() failed",__func__);
699
	  rv = -1;
700
	  goto end;
701
	}
702
    }
703
    else {
704
	MDBGLOG("net","ERROR\t[%s()]: g_tcp_bind_flags() failed",__func__);
705
	rv = -1;
706
	goto end;
346
    }
707
    }
347
  }
708
  }
348
  else if (self->mode == 2) /* unix socket */
709
  else if (self->mode == 2) /* unix socket */
349
  {
710
  {
350
    g_free(self->listen_filename);
711
    g_free(self->listen_filename);
351
    self->listen_filename = 0;
712
    self->listen_filename = NULL;
352
    g_file_delete(port);
713
    g_file_delete(port);
353
    self->sck = g_tcp_local_socket();
714
    self->sck = g_tcp_local_socket();
354
    g_tcp_set_non_blocking(self->sck);
715
    g_tcp_set_non_blocking(self->sck);
355
    if (g_tcp_local_bind(self->sck, port) == 0)
716
    if (g_tcp_local_bind(self->sck, port) == 0) {
356
    {
717
        self->listen_filename = g_strdup(port);
357
      self->listen_filename = g_strdup(port);
718
        if (g_tcp_listen(self->sck) == 0)
358
      if (g_tcp_listen(self->sck) == 0)
719
        {
359
      {
720
          g_chmod_hex(port, 0xffff);
360
        g_chmod_hex(port, 0xffff);
721
          self->status = 1; /* ok */
361
        self->status = 1; /* ok */
722
          self->type1 = 1; /* listener */
362
        self->type1 = 1; /* listener */
723
          rv = 0;
363
        return 0;
724
	  goto end;
364
      }
725
        }
365
    }
726
	else {
727
	  MDBGLOG("net","ERROR\t[%s()]: g_tcp_listen() failed",__func__);
728
	  rv = -1;
729
	  goto end;
730
	}
731
    }
732
    else {
733
	MDBGLOG("net","ERROR\t[%s()]: g_tcp_local_bind() failed",__func__);
734
	rv = -1;
735
	goto end;
736
    }
737
  }
738
  else {
739
    MDBGLOG("net","ERROR\t[%s()]: unrecognized mode (self->mode = %d)",__func__,self->mode);
740
    rv = -1;
741
    goto end;
366
  }
742
  }
367
  return 1;
743
 end:;
744
  return rv;
368
}
745
}
369
746
370
/*****************************************************************************/
747
/*****************************************************************************/
371
struct stream* APP_CC
748
int APP_CC
372
trans_get_in_s(struct trans* self)
749
trans_stop_listening(struct trans * self) {
373
{
750
  int rv = 0;
374
  return self->in_s;
751
  if (self == NULL) {
752
    rv = -1;
753
  }
754
  else {
755
    if (self->sck != 0 && self->mode == 3) {
756
      g_file_close(self->sck);
757
    }
758
    else if (self->sck != 0) {
759
      g_tcp_close(self->sck);
760
    }
761
    self->sck = 0;
762
    self->status = 0; /* disconnected */
763
    self->type1 = 0; /* none */
764
  }
765
  return rv;
375
}
766
}
376
767
377
/*****************************************************************************/
768
/*****************************************************************************/
378
struct stream* APP_CC
769
struct stream* APP_CC
379
trans_get_out_s(struct trans* self, int size)
770
trans_get_in_s(struct trans* self) {
380
{
771
  struct stream * rv = (struct stream *)NULL;
381
  init_stream(self->out_s, size);
772
  // MDBGLOG("trans","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
382
  return self->out_s;
773
  if (self == NULL) {
774
    rv = (struct stream *)NULL;
775
  }
776
  else {
777
    rv = self->in_s;
778
  }
779
  return rv;
780
}
781
782
/*****************************************************************************/
783
struct stream * APP_CC
784
trans_get_out_s(struct trans * self, size_t size) {
785
  struct stream * rv = (struct stream *)NULL;
786
787
  // MDBGLOG("trans","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
788
789
  if (self == NULL) {
790
    rv = (struct stream *)NULL;
791
  }
792
  else {
793
    init_stream(self->out_s, size);
794
    rv = self->out_s;
795
  }
796
  return rv;
797
}
798
799
/*****************************************************************************/
800
ptrdiff_t APP_CC
801
trans_get_read_so_far(struct trans* self) {
802
  ptrdiff_t rv = 0;
803
  if (self == NULL) {
804
    rv = -1;
805
  }
806
  else {
807
    rv = self->in_s->end - self->in_s->data;
808
  }
809
  return rv;
810
}
811
812
/*****************************************************************************/
813
ptrdiff_t APP_CC
814
trans_get_written_so_far(struct trans* self) {
815
  ptrdiff_t rv = 0;
816
  if (self == NULL) {
817
    rv = -1;
818
  }
819
  else if (self->out_s == NULL || self->out_s->data == NULL || self->out_s->end == NULL || self->out_s->end == self->out_s->data || self->out_s->p == NULL || self->out_s->p == self->out_s->data) {
820
    rv = 0;
821
  }
822
  else {
823
    rv = self->out_s->p - self->out_s->data;
824
  }
825
  return rv;
383
}
826
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/common/trans.h (-16 / +62 lines)
 Lines 26-74    Link Here 
26
#if !defined(TRANS_H)
26
#if !defined(TRANS_H)
27
#define TRANS_H
27
#define TRANS_H
28
28
29
#define __XRDP_TRANS_LOCKS__
30
//#undef __XRDP_TRANS_LOCKS__
31
32
#include <stddef.h>
29
#include "arch.h"
33
#include "arch.h"
30
#include "parse.h"
34
#include "parse.h"
31
35
36
#if defined(__XRDP_TRANS_LOCKS__)
37
#include "thread_calls.h"
38
#include "thread_macros.h"
39
#endif
40
32
struct trans; /* forward declaration */
41
struct trans; /* forward declaration */
33
42
34
typedef int (*ttrans_data_in)(struct trans* self);
43
typedef size_t (*ttrans_data_in)(struct trans* self);
35
typedef int (*ttrans_conn_in)(struct trans* self, struct trans* new_self);
44
typedef int (*ttrans_conn_in)(struct trans* self, struct trans* new_self);
36
45
37
struct trans
46
typedef struct trans {
38
{
39
  tbus sck;
47
  tbus sck;
40
  int mode; /* 1 tcp, 2 unix socket */
48
  tbus sck_out;
49
  int mode; /* 1 = tcp, 2 = unix socket, 3 = FIFO */
41
  int status;
50
  int status;
42
  int type1; /* 1 listener 2 server 3 client */
51
  int type1; /* 1 listener 2 server 3 client */
52
  int ready;
53
  int send_flags;
54
  double rtime;
43
  ttrans_data_in trans_data_in;
55
  ttrans_data_in trans_data_in;
44
  ttrans_conn_in trans_conn_in;
56
  ttrans_conn_in trans_conn_in;
45
  void* callback_data;
57
  void * callback_data;
46
  int header_size;
58
  int header_size;
47
  struct stream* in_s;
59
  struct stream* in_s;
48
  struct stream* out_s;
60
  struct stream* out_s;
49
  char* listen_filename;
61
  tc_t *        lock;
50
};
62
  tc_t *        listen_lock;
63
  unsigned char locked;
64
  unsigned char listening;
65
  unsigned char running;
66
  char * listen_filename;
67
} trans_t;
51
68
52
struct trans* APP_CC
69
struct trans* APP_CC
53
trans_create(int mode, int in_size, int out_size);
70
trans_create(int mode, size_t in_size, size_t out_size);
54
void APP_CC
71
void APP_CC
55
trans_delete(struct trans* self);
72
trans_delete(struct trans* self);
56
int APP_CC
73
int APP_CC
57
trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout);
74
trans_get_wait_objs(struct trans *, tbus [], ptrdiff_t *, int *);
58
int APP_CC
75
int APP_CC
59
trans_check_wait_objs(struct trans* self);
76
trans_check_wait_objs(struct trans *);
77
ptrdiff_t APP_CC
78
trans_force_read(struct trans *, size_t);
79
ptrdiff_t APP_CC
80
trans_read(struct trans *, size_t);
81
ptrdiff_t APP_CC
82
trans_force_write(struct trans* self);
60
int APP_CC
83
int APP_CC
61
trans_force_read(struct trans* self, int size);
84
trans_connect(struct trans *, const char *, const char *, int);
62
int APP_CC
85
int APP_CC
63
trans_force_write(struct trans* self);
86
trans_disconnect(struct trans *);
87
int APP_CC
88
trans_attach(struct trans * self, int sck);
89
int APP_CC
90
trans_detach(struct trans *);
64
int APP_CC
91
int APP_CC
65
trans_connect(struct trans* self, const char* server, const char* port,
92
trans_listen(struct trans *, char *);
66
              int timeout);
67
int APP_CC
93
int APP_CC
68
trans_listen(struct trans* self, char* port);
94
trans_stop_listening(struct trans *);
69
struct stream* APP_CC
95
struct stream* APP_CC
70
trans_get_in_s(struct trans* self);
96
trans_get_in_s(struct trans* self);
71
struct stream* APP_CC
97
struct stream* APP_CC
72
trans_get_out_s(struct trans* self, int size);
98
trans_get_out_s(struct trans* self, size_t size);
99
ptrdiff_t APP_CC
100
trans_get_read_so_far(struct trans* self);
101
ptrdiff_t APP_CC
102
trans_get_written_so_far(struct trans* self);
103
104
105
#define LOCAL_STREAM_STRUCT(inx) inx ## _stream
106
#define LOCAL_STREAM_DATA(inx) inx ## _data
107
#define	LOCAL_STREAM(inx)				\
108
    char LOCAL_STREAM_DATA(inx)[MAX_STREAM];		\
109
    struct stream LOCAL_STREAM_STRUCT(inx);		\
110
    struct stream * inx = &(LOCAL_STREAM_STRUCT(inx));	\
111
    {							\
112
      g_memset(LOCAL_STREAM_DATA(inx),0x00,sizeof(LOCAL_STREAM_DATA(inx)));	\
113
      g_memset(inx,0x00,sizeof(struct stream));		\
114
      inx->data = LOCAL_STREAM_DATA(inx);		\
115
      inx->p = inx->data;				\
116
      inx->end = inx->data;				\
117
      inx->size = MAX_STREAM;				\
118
    }	
73
119
74
#endif
120
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/configure.ac (+31 lines)
 Lines 20-25    Link Here 
20
              [pamuserpass=true], [pamuserpass=false])
20
              [pamuserpass=true], [pamuserpass=false])
21
AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$pamuserpass = xtrue])
21
AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$pamuserpass = xtrue])
22
22
23
AC_ARG_ENABLE(pulse, AS_HELP_STRING([--enable-pulse],
24
              [Build with PulseAudio support (default: yes)]),
25
              [pulse=true], [pulse=false])
26
	      if test "${enable_pulse}" != "no"
27
		then
28
		PKG_CHECK_MODULES(PULSE, libpulse >= 0.9.11,
29
		  [
30
#			XRDP_ADD_PLUGIN([pulse])
31
#			XRDP_ADD_CFLAGS([pulse],[${PULSE_CFLAGS}])
32
#			XRDP_ADD_LDFLAGS([pulse],[${PULSE_LIBS}])
33
		  ]
34
			)
35
		fi
36
AM_CONDITIONAL(SESMAN_PULSE, [test x$pulse = xtrue])
37
38
AC_ARG_ENABLE(nl, AS_HELP_STRING([--enable-nl],
39
              [Build with netlink support (default: yes)]),
40
              [nl=true], [nl=false])
41
	      if test "${enable_nl}" != "no"
42
		then
43
		PKG_CHECK_MODULES(NETLINK, libnl-1 >= 0.9.11,
44
		  [
45
#			XRDP_ADD_PLUGIN([nl])
46
#			XRDP_ADD_CFLAGS([nl],[${NETLINK_CFLAGS}])
47
#			XRDP_ADD_LDFLAGS([nl],[${NETLINK_LIBS}])
48
		  ]
49
			)
50
		fi
51
AM_CONDITIONAL(SESMAN_NETLINK, [test x$nl = xtrue])
52
23
# checking for openssl
53
# checking for openssl
24
AC_CHECK_HEADER([openssl/rc4.h], [],
54
AC_CHECK_HEADER([openssl/rc4.h], [],
25
  [AC_MSG_ERROR([please install libssl-dev or openssl-devel])],
55
  [AC_MSG_ERROR([please install libssl-dev or openssl-devel])],
 Lines 60-65    Link Here 
60
                 sesman/tools/Makefile
90
                 sesman/tools/Makefile
61
                 sesman/sessvc/Makefile
91
                 sesman/sessvc/Makefile
62
                 sesman/chansrv/Makefile
92
                 sesman/chansrv/Makefile
93
                 sesman/dynamic/Makefile
63
                 keygen/Makefile
94
                 keygen/Makefile
64
                 docs/Makefile
95
                 docs/Makefile
65
                 docs/man/Makefile
96
                 docs/man/Makefile
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/debian/changelog (+7 lines)
 Lines 1-3    Link Here 
1
xrdp (0.5.0~20101104bzr-1) unstable; urgency=low
2
3
  * bzr branch lp:posixrdp
4
    (http://bazaar.launchpad.net/~ryanaxp/posixrdp/devel/files)
5
6
 -- Arvid Requate <requate@univention.de>  Thu, 04 Nov 2010 10:18:15 +0100
7
1
xrdp (0.5.0~20100303cvs-6) unstable; urgency=low
8
xrdp (0.5.0~20100303cvs-6) unstable; urgency=low
2
9
3
  * Add a patch to fix Alt-Gr issues with Windows TS client.
10
  * Add a patch to fix Alt-Gr issues with Windows TS client.
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/debian/patches/series (+2 lines)
 Lines 3-5    Link Here 
3
05-default-keymap.patch
3
05-default-keymap.patch
4
06-xrdp_pidfile_early.patch
4
06-xrdp_pidfile_early.patch
5
alt-gr-fix.patch
5
alt-gr-fix.patch
6
sessionbroker.patch
7
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/debian/.pc/applied-patches (+2 lines)
Line 0    Link Here 
1
--- a/rdp/rdp.c	
Line 0    Link Here 
1
01reuse-session.patch
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/debian/.pc/.version (+1 lines)
Line 0    Link Here 
1
2
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/debian/rules (-2 / +3 lines)
 Lines 5-12    Link Here 
5
	dh $@
5
	dh $@
6
6
7
override_dh_auto_configure:
7
override_dh_auto_configure:
8
	export PKG_CONFIG=/usr/bin/pkg-config
8
	./bootstrap
9
	./bootstrap
9
	./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
10
	./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-pulse --disable-nl
10
	find -name Makefile | while read i; do sed -e 's#\(XRDP_PID_PATH.*/run\)#\1/xrdp#g' -i "$$i"; done
11
	find -name Makefile | while read i; do sed -e 's#\(XRDP_PID_PATH.*/run\)#\1/xrdp#g' -i "$$i"; done
11
12
12
override_dh_makeshlibs:
13
override_dh_makeshlibs:
 Lines 21-27    Link Here 
21
	# Clean up some files
22
	# Clean up some files
22
	rm debian/xrdp/etc/xrdp/xrdp.sh
23
	rm debian/xrdp/etc/xrdp/xrdp.sh
23
	rm debian/xrdp/usr/lib/xrdp/*a
24
	rm debian/xrdp/usr/lib/xrdp/*a
24
	rm debian/xrdp/usr/bin/xrdp-sestest
25
	#rm debian/xrdp/usr/bin/xrdp-sestest
25
	# Use our own startwm.sh
26
	# Use our own startwm.sh
26
	install -m 755 debian/startwm.sh debian/xrdp/etc/xrdp
27
	install -m 755 debian/startwm.sh debian/xrdp/etc/xrdp
27
	# Move rsakeys to documentation
28
	# Move rsakeys to documentation
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/design.txt (-1 / +1 lines)
 Lines 7-13    Link Here 
7
one could be running a X11 session
7
one could be running a X11 session
8
clients control the screen size and color depth
8
clients control the screen size and color depth
9
9
10
all controlled by a cofiguaration file.
10
all controlled by a configuration file.
11
11
12
you can create a lib or use a lib with your executable that talks
12
you can create a lib or use a lib with your executable that talks
13
to xrdp server.
13
to xrdp server.
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/docs/ckill.sh (+18 lines)
Line 0    Link Here 
1
#!/bin/sh
2
# ps aux | grep X ; ps aux | grep rdp ; ps aux | grep ssh-agent
3
4
invoke-rc.d xrdp stop
5
unset TMPARGS
6
TMP=$(ps -C Xvnc,X11rdp,xrdp,xrdp-sesman,xrdp-chansrv,xrdp-sessvc,startwm.sh,ssh-agent,xrdp-sesadmin,xrdp-sesrun,xrdp_drdynvc_interface,xrdp_rdpeai -o pid)
7
for f in ${TMP}
8
do
9
  if [ "${f}" != "PID"  ]; then
10
TMPARGS=${TMPARGS}" ${f}"
11
  fi
12
done
13
/bin/kill -s KILL ${TMPARGS} &>0
14
rm /tmp/xrdp_* &>0
15
rm -r /tmp/.X1* &>0
16
rm /var/run/xrdp*pid &>0
17
18
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/keygen/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 14-17    Link Here 
14
xrdp_keygen_SOURCES = keygen.c
22
xrdp_keygen_SOURCES = keygen.c
15
23
16
xrdp_keygen_LDADD = \
24
xrdp_keygen_LDADD = \
17
  $(top_srcdir)/common/libcommon.la
25
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/libxrdp.c (-32 / +35 lines)
 Lines 133-141    Link Here 
133
int EXPORT_CC
133
int EXPORT_CC
134
libxrdp_send_palette(struct xrdp_session* session, int* palette)
134
libxrdp_send_palette(struct xrdp_session* session, int* palette)
135
{
135
{
136
  int i;
136
  int i = 0;
137
  int color;
137
  int color = 0;
138
  struct stream* s;
138
  struct stream* s = (struct stream *)NULL;
139
139
140
  if (session->client_info->bpp > 8)
140
  if (session->client_info->bpp > 8)
141
  {
141
  {
 Lines 173-196    Link Here 
173
libxrdp_send_bitmap(struct xrdp_session* session, int width, int height,
173
libxrdp_send_bitmap(struct xrdp_session* session, int width, int height,
174
                    int bpp, char* data, int x, int y, int cx, int cy)
174
                    int bpp, char* data, int x, int y, int cx, int cy)
175
{
175
{
176
  int line_size;
176
  int data_size = 0;
177
  int i;
177
  int line_size = 0;
178
  int j;
178
  int i = 0;
179
  int total_lines;
179
  int j = 0;
180
  int lines_sending;
180
  int total_lines = 0;
181
  int Bpp;
181
  int lines_sending = 0;
182
  int e;
182
  int Bpp = 0;
183
  int bufsize;
183
  int e = 0;
184
  int total_bufsize;
184
  int bufsize = 0;
185
  int num_updates;
185
  int total_bufsize = 0;
186
  char* p_num_updates;
186
  int num_updates = 0;
187
  char* p;
187
  char* p_num_updates = (char *)NULL;
188
  char* q;
188
  char* p = (char *)NULL;
189
  struct stream* s;
189
  char* q = (char *)NULL;
190
  struct stream* temp_s;
190
  struct stream* s = (struct stream *)NULL;
191
  struct stream* temp_s = (struct stream *)NULL;
191
192
192
  DEBUG(("libxrdp_send_bitmap sending bitmap"));
193
  DEBUG(("libxrdp_send_bitmap sending bitmap"));
193
  Bpp = (bpp + 7) / 8;
194
  Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
194
  e = width % 4;
195
  e = width % 4;
195
  if (e != 0)
196
  if (e != 0)
196
  {
197
  {
 Lines 290-295    Link Here 
290
  }
291
  }
291
  else
292
  else
292
  {
293
  {
294
    lines_sending = 0;
295
    data_size = width * height * Bpp;
293
    total_lines = height;
296
    total_lines = height;
294
    i = 0;
297
    i = 0;
295
    p = data;
298
    p = data;
 Lines 621-630    Link Here 
621
libxrdp_query_channel(struct xrdp_session* session, int index,
624
libxrdp_query_channel(struct xrdp_session* session, int index,
622
                      char* channel_name, int* channel_flags)
625
                      char* channel_name, int* channel_flags)
623
{
626
{
624
  int count;
627
  int count = 0;
625
  struct xrdp_rdp* rdp;
628
  struct xrdp_rdp* rdp = (struct xrdp_rdp *)NULL;
626
  struct xrdp_mcs* mcs;
629
  struct xrdp_mcs* mcs = (struct xrdp_mcs *)NULL;
627
  struct mcs_channel_item* channel_item;
630
  struct mcs_channel_item* channel_item = (struct mcs_channel_item *)NULL;
628
631
629
  rdp = (struct xrdp_rdp*)session->rdp;
632
  rdp = (struct xrdp_rdp*)session->rdp;
630
  mcs = rdp->sec_layer->mcs_layer;
633
  mcs = rdp->sec_layer->mcs_layer;
 Lines 657-667    Link Here 
657
int EXPORT_CC
660
int EXPORT_CC
658
libxrdp_get_channel_id(struct xrdp_session* session, char* name)
661
libxrdp_get_channel_id(struct xrdp_session* session, char* name)
659
{
662
{
660
  int index;
663
  int index = 0;
661
  int count;
664
  int count = 0;
662
  struct xrdp_rdp* rdp;
665
  struct xrdp_rdp* rdp = NULL;
663
  struct xrdp_mcs* mcs;
666
  struct xrdp_mcs* mcs = NULL;
664
  struct mcs_channel_item* channel_item;
667
  struct mcs_channel_item* channel_item = NULL;
665
668
666
  rdp = (struct xrdp_rdp*)session->rdp;
669
  rdp = (struct xrdp_rdp*)session->rdp;
667
  mcs = rdp->sec_layer->mcs_layer;
670
  mcs = rdp->sec_layer->mcs_layer;
 Lines 687-696    Link Here 
687
                        char* data, int data_len,
690
                        char* data, int data_len,
688
                        int total_data_len, int flags)
691
                        int total_data_len, int flags)
689
{
692
{
690
  struct xrdp_rdp* rdp;
693
  struct xrdp_rdp* rdp = NULL;
691
  struct xrdp_sec* sec;
694
  struct xrdp_sec* sec = NULL;
692
  struct xrdp_channel* chan;
695
  struct xrdp_channel* chan = NULL;
693
  struct stream* s;
696
  struct stream* s = NULL;
694
697
695
  rdp = (struct xrdp_rdp*)session->rdp;
698
  rdp = (struct xrdp_rdp*)session->rdp;
696
  sec = rdp->sec_layer;
699
  sec = rdp->sec_layer;
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/libxrdpinc.h (-2 / +126 lines)
 Lines 20-33    Link Here 
20
20
21
*/
21
*/
22
22
23
#if !defined(LIBXRDPINC_H)
23
#ifndef LIBXRDPINC_H
24
#define LIBXRDPINC_H
24
#define LIBXRDPINC_H
25
25
26
#include <stddef.h>
27
#include <stdint.h>
28
#include <stdio.h>
29
#include <string.h>
30
#include <wchar.h>
31
32
#define RNS_UD_COLOR_4BPP			0xca00
33
#define RNS_UD_COLOR_8BPP			0xca01
34
35
#define RNS_UD_24BPP_SUPPORT			0x0001
36
#define RNS_UD_16BPP_SUPPORT			0x0002
37
#define RNS_UD_15BPP_SUPPORT			0x0004
38
#define RNS_UD_32BPP_SUPPORT			0x0008
39
40
#define RNS_UD_CS_SUPPORT_ERRINFO_PDU		0x0001
41
#define RNS_UD_CS_WANT_32BPP_SESSION		0x0002
42
#define RNS_UD_CS_SUPPORT_STATUSINFO_PDU	0x0004
43
#define RNS_UD_CS_STRONG_ASYMMETRIC_KEYS	0x0008
44
#define RNS_UD_CS_VALID_CONNECTION_TYPE		0x0020
45
#define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU	0x0040
46
47
#define CONNECTION_TYPE_MODEM			1
48
#define CONNECTION_TYPE_BROADBAND_LOW		2
49
#define CONNECTION_TYPE_SATELLITE		3
50
#define CONNECTION_TYPE_BROADBAND_HIGH		4
51
#define CONNECTION_TYPE_WAN			5
52
#define CONNECTION_TYPE_LAN			6
53
54
/*	Constants used in the TS_INFO_PACKET structure	*/
55
#define INFO_MOUSE			0x00000001
56
#define INFO_DISABLECTRLALTDEL		0x00000002
57
#define INFO_AUTOLOGON			0x00000008
58
#define INFO_UNICODE			0x00000010
59
#define INFO_MAXIMIZESHELL		0x00000020
60
#define INFO_LOGONNOTIFY		0x00000040
61
#define INFO_COMPRESSION		0x00000080
62
#define CompressionTypeMask		0x00001E00
63
#define   PACKET_COMPR_TYPE_8K		0
64
#define   PACKET_COMPR_TYPE_64K		1
65
#define   PACKET_COMPR_TYPE_RDP6	2
66
#define   PACKET_COMPR_TYPE_RDP61	3
67
#define INFO_ENABLEWINDOWSKEY		0x00000100
68
#define INFO_REMOTECONSOLEAUDIO		0x00002000
69
#define INFO_FORCE_ENCRYPTED_CS_PDU	0x00004000
70
#define INFO_RAIL			0x00008000
71
#define INFO_LOGONERRORS		0x00010000
72
#define INFO_MOUSE_HAS_WHEEL		0x00020000
73
#define INFO_PASSWORD_IS_SC_PIN		0x00040000
74
#define INFO_NOAUDIOPLAYBACK		0x00080000
75
#define INFO_USING_SAVED_CREDS		0x00100000
76
77
/* bit flags in the "performanceFlags" field */
78
#define PERF_DISABLE_WALLPAPER		0x00000001
79
#define PERF_DISABLE_FULLWINDOWDRAG	0x00000002
80
#define PERF_DISABLE_MENUANIMATIONS	0x00000004
81
#define PERF_DISABLE_THEMING		0x00000008
82
#define PERF_RESERVED1			0x00000010
83
#define PERF_DISABLE_CURSOR_SHADOW	0x00000020
84
#define PERF_DISABLE_CURSORSETTINGS	0x00000040
85
#define PERF_ENABLE_FONT_SMOOTHING	0x00000080
86
#define PERF_ENABLE_DESKTOP_COMPOSITION	0x00000100
87
#define PERF_RESERVED2			0x80000000
88
89
#define CI_AF_INET			0x0002
90
#define CI_AF_INET6			0x0017
91
92
/* TS_GENERAL_CAPABILITYSET */
93
#define OSMAJORTYPE_UNSPECIFIED		0x0000
94
#define OSMAJORTYPE_WINDOWS		0x0001
95
#define OSMAJORTYPE_OS2			0x0002
96
#define OSMAJORTYPE_MACINTOSH		0x0003
97
#define OSMAJORTYPE_UNIX		0x0004
98
#define OSMINORTYPE_UNSPECIFIED		0x0000
99
#define OSMINORTYPE_WINDOWS_31X		0x0001
100
#define TS_OSMINORTYPE_WINDOWS_95	0x0002
101
#define TS_OSMINORTYPE_WINDOWS_NT	0x0003
102
#define TS_OSMINORTYPE_OS2_V21		0x0004
103
#define TS_OSMINORTYPE_POWER_PC		0x0005
104
#define TS_OSMINORTYPE_MACINTOSH	0x0006
105
#define TS_OSMINORTYPE_NATIVE_XSERVER	0x0007
106
#define TS_OSMINORTYPE_PSEUDO_XSERVER	0x0008
107
108
#define DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY	0x02
109
#define DRAW_ALLOW_COLOR_SUBSAMPLING	0x04
110
#define DRAW_ALLOW_SKIP_ALPHA		0x08
111
112
26
struct xrdp_client_info
113
struct xrdp_client_info
27
{
114
{
28
  int bpp;
115
  int bpp;
29
  int width;
116
  int width;
30
  int height;
117
  int height;
118
  uint32_t	version;
119
  uint16_t	colorDepth;
120
  uint16_t	postBeta2ColorDepth;
121
  uint16_t	highColorDepth;
122
  uint16_t	supportedColorDepths;
123
  uint16_t	earlyCapabilityFlags;
124
  uint32_t	keyboardLayout;
125
  uint32_t	keyboardType;
126
  uint32_t	keyboardSubType;
127
  uint32_t	keyboardFunctionKey;
128
  uint16_t	imeFileName[32];
129
  uint32_t	serialNumber;
130
  uint32_t	clientBuild;
131
  uint16_t	clientName[16];
132
  uint16_t	clientProductId;
133
  uint8_t	clientDigProductId[64];
134
  uint8_t	connectionType;
135
  uint32_t	serverSelectedProtocol;
31
  /* bitmap cache info */
136
  /* bitmap cache info */
32
  int cache1_entries;
137
  int cache1_entries;
33
  int cache1_size;
138
  int cache1_size;
 Lines 60-68    Link Here 
60
  int channel_code; /* 0 = no channels 1 = channels */
165
  int channel_code; /* 0 = no channels 1 = channels */
61
  int sound_code; /* 1 = leave sound at server */
166
  int sound_code; /* 1 = leave sound at server */
62
  int is_mce;
167
  int is_mce;
63
  int rdp5_performanceflags;
168
  uint32_t rdp5_performanceflags;
64
  int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache
169
  int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache
65
                           2 = arbitrary dimensions */
170
                           2 = arbitrary dimensions */
171
  uint32_t flags;	/* from the TS_INFO_PACKET structure (see MS-RDPBCGR.pdf, v20091104, at section 2.2.1.11.1.1, page 58 et seq. */
172
173
  /* TS_EXTENDED_INFO_PACKET	*/
174
  uint32_t		CodePage;
175
  uint16_t		clientAddressFamily;		/* 0x0002 = AF_INET; 0x0017 = AF_INET6 */
176
  uint16_t		cbClientAddress;		/* size in bytes of the data in the "clientAddress" field (including the length of the required NULL terminator) */
177
  uint8_t *		clientAddress;
178
  uint16_t		cbClientDir;
179
  uint8_t *		clientDir;
180
  uint8_t 		clientTimeZone[172];		/* TS_TIME_ZONE_INFORMATION */
181
  uint16_t		cbAutoReconnectLen;
182
  uint8_t		autoReconnectCookie[28];	/* ARC_CS_PRIVATE_PACKET */
183
  uint32_t		clientSessionId;
66
};
184
};
67
185
68
struct xrdp_brush
186
struct xrdp_brush
 Lines 215-218    Link Here 
215
                          int width, int height, int bpp, int type,
333
                          int width, int height, int bpp, int type,
216
                          int size, char* data, int cache_id);
334
                          int size, char* data, int cache_id);
217
335
336
/*	Unicode junk	*/
337
typedef uint16_t UTF16;
338
typedef uint32_t UTF32;
339
UTF32 utf16_to_utf32(UTF16, UTF16);
340
UTF16 * utf32_to_utf16(UTF32);
341
218
#endif
342
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 23-26    Link Here 
23
  xrdp_bitmap_compress.c
31
  xrdp_bitmap_compress.c
24
32
25
libxrdp_la_LIBADD = \
33
libxrdp_la_LIBADD = \
26
  $(top_srcdir)/common/libcommon.la
34
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/xrdp_bitmap_compress.c (-1 / +264 lines)
 Lines 950-956    Link Here 
950
  }
950
  }
951
  else if ((bpp == 15) || (bpp == 16))
951
  else if ((bpp == 15) || (bpp == 16))
952
  {
952
  {
953
    mix = 0xffff;
953
    mix = (bpp == 15) ? 0xba1f : 0xffff;
954
    out_count = end * 2;
954
    out_count = end * 2;
955
    line = in_data + width * start_line * 2;
955
    line = in_data + width * start_line * 2;
956
    while (start_line >= 0 && out_count < 32768)
956
    while (start_line >= 0 && out_count < 32768)
 Lines 1470-1474    Link Here 
1470
      OUT_COPY_COUNT3(count, s, temp_s);
1470
      OUT_COPY_COUNT3(count, s, temp_s);
1471
    }
1471
    }
1472
  }
1472
  }
1473
  else if (bpp == 32)
1474
  {
1475
    mix = 0xffffff;
1476
    out_count = end * 4;
1477
    line = in_data + width * start_line * 4;
1478
    while (start_line >= 0 && out_count < 32768)
1479
    {
1480
      i = (s->p - s->data) + count * 4;
1481
      if (i - (color_count * 3) >= byte_limit &&
1482
          i - (bicolor_count * 3) >= byte_limit &&
1483
          i - (fill_count * 3) >= byte_limit &&
1484
          i - (mix_count * 3) >= byte_limit &&
1485
          i - (fom_count * 3) >= byte_limit)
1486
      {
1487
        break;
1488
      }
1489
      out_count += end * 4;
1490
      for (i = 0; i < end; i++)
1491
      {
1492
        /* read next pixel */
1493
        IN_PIXEL32(line, i, 0, width, last_pixel, pixel);
1494
        IN_PIXEL32(last_line, i, 0, width, last_ypixel, ypixel);
1495
        if (!TEST_FILL)
1496
        {
1497
          if (fill_count > 3 &&
1498
              fill_count >= color_count &&
1499
              fill_count >= bicolor_count &&
1500
              fill_count >= mix_count &&
1501
              fill_count >= fom_count)
1502
          {
1503
            count -= fill_count;
1504
            OUT_COPY_COUNT3(count, s, temp_s);
1505
            OUT_FILL_COUNT3(fill_count, s);
1506
            RESET_COUNTS;
1507
          }
1508
          fill_count = 0;
1509
        }
1510
        if (!TEST_MIX)
1511
        {
1512
          if (mix_count > 3 &&
1513
              mix_count >= fill_count &&
1514
              mix_count >= bicolor_count &&
1515
              mix_count >= color_count &&
1516
              mix_count >= fom_count)
1517
          {
1518
            count -= mix_count;
1519
            OUT_COPY_COUNT3(count, s, temp_s);
1520
            OUT_MIX_COUNT3(mix_count, s);
1521
            RESET_COUNTS;
1522
          }
1523
          mix_count = 0;
1524
        }
1525
        if (!TEST_COLOR)
1526
        {
1527
          if (color_count > 3 &&
1528
              color_count >= fill_count &&
1529
              color_count >= bicolor_count &&
1530
              color_count >= mix_count &&
1531
              color_count >= fom_count)
1532
          {
1533
            count -= color_count;
1534
            OUT_COPY_COUNT3(count, s, temp_s);
1535
            OUT_COLOR_COUNT3(color_count, s, last_pixel);
1536
            RESET_COUNTS;
1537
          }
1538
          color_count = 0;
1539
        }
1540
        if (!TEST_BICOLOR)
1541
        {
1542
          if (bicolor_count > 3 &&
1543
              bicolor_count >= fill_count &&
1544
              bicolor_count >= color_count &&
1545
              bicolor_count >= mix_count &&
1546
              bicolor_count >= fom_count)
1547
          {
1548
            if ((bicolor_count % 2) == 0)
1549
            {
1550
              count -= bicolor_count;
1551
              OUT_COPY_COUNT3(count, s, temp_s);
1552
              OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2);
1553
            }
1554
            else
1555
            {
1556
              bicolor_count--;
1557
              count -= bicolor_count;
1558
              OUT_COPY_COUNT3(count, s, temp_s);
1559
              OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1);
1560
            }
1561
            RESET_COUNTS;
1562
          }
1563
          bicolor_count = 0;
1564
          bicolor1 = last_pixel;
1565
          bicolor2 = pixel;
1566
          bicolor_spin = 0;
1567
        }
1568
        if (!TEST_FOM)
1569
        {
1570
          if (fom_count > 3 &&
1571
              fom_count >= fill_count &&
1572
              fom_count >= color_count &&
1573
              fom_count >= mix_count &&
1574
              fom_count >= bicolor_count)
1575
          {
1576
            count -= fom_count;
1577
            OUT_COPY_COUNT3(count, s, temp_s);
1578
            OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len);
1579
            RESET_COUNTS;
1580
          }
1581
          fom_count = 0;
1582
          fom_mask_len = 0;
1583
        }
1584
        if (TEST_FILL)
1585
        {
1586
          fill_count++;
1587
        }
1588
        if (TEST_MIX)
1589
        {
1590
          mix_count++;
1591
        }
1592
        if (TEST_COLOR)
1593
        {
1594
          color_count++;
1595
        }
1596
        if (TEST_BICOLOR)
1597
        {
1598
          bicolor_spin = !bicolor_spin;
1599
          bicolor_count++;
1600
        }
1601
        if (TEST_FOM)
1602
        {
1603
          if ((fom_count % 8) == 0)
1604
          {
1605
            fom_mask[fom_mask_len] = 0;
1606
            fom_mask_len++;
1607
          }
1608
          if (pixel == (ypixel ^ mix))
1609
          {
1610
            fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8));
1611
          }
1612
          fom_count++;
1613
        }
1614
	out_uint8(temp_s, 0x00);
1615
        out_uint8(temp_s, pixel & 0xff);
1616
        out_uint8(temp_s, (pixel >> 8) & 0xff);
1617
        out_uint8(temp_s, (pixel >> 16) & 0xff);
1618
        count++;
1619
        last_pixel = pixel;
1620
        last_ypixel = ypixel;
1621
      }
1622
      /* can't take fix, mix, or fom past first line */
1623
      if (last_line == 0)
1624
      {
1625
        if (fill_count > 3 &&
1626
            fill_count >= color_count &&
1627
            fill_count >= bicolor_count &&
1628
            fill_count >= mix_count &&
1629
            fill_count >= fom_count)
1630
        {
1631
          count -= fill_count;
1632
          OUT_COPY_COUNT3(count, s, temp_s);
1633
          OUT_FILL_COUNT3(fill_count, s);
1634
          RESET_COUNTS;
1635
        }
1636
        fill_count = 0;
1637
        if (mix_count > 3 &&
1638
            mix_count >= fill_count &&
1639
            mix_count >= bicolor_count &&
1640
            mix_count >= color_count &&
1641
            mix_count >= fom_count)
1642
        {
1643
          count -= mix_count;
1644
          OUT_COPY_COUNT3(count, s, temp_s);
1645
          OUT_MIX_COUNT3(mix_count, s);
1646
          RESET_COUNTS;
1647
        }
1648
        mix_count = 0;
1649
        if (fom_count > 3 &&
1650
            fom_count >= fill_count &&
1651
            fom_count >= color_count &&
1652
            fom_count >= mix_count &&
1653
            fom_count >= bicolor_count)
1654
        {
1655
          count -= fom_count;
1656
          OUT_COPY_COUNT3(count, s, temp_s);
1657
          OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len);
1658
          RESET_COUNTS;
1659
        }
1660
        fom_count = 0;
1661
        fom_mask_len = 0;
1662
      }
1663
      last_line = line;
1664
      line = line - width * 4;
1665
      start_line--;
1666
      lines_sent++;
1667
    }
1668
    if (fill_count > 3 &&
1669
        fill_count >= color_count &&
1670
        fill_count >= bicolor_count &&
1671
        fill_count >= mix_count &&
1672
        fill_count >= fom_count)
1673
    {
1674
      count -= fill_count;
1675
      OUT_COPY_COUNT3(count, s, temp_s);
1676
      OUT_FILL_COUNT3(fill_count, s);
1677
    }
1678
    else if (mix_count > 3 &&
1679
             mix_count >= color_count &&
1680
             mix_count >= bicolor_count &&
1681
             mix_count >= fill_count &&
1682
             mix_count >= fom_count)
1683
    {
1684
      count -= mix_count;
1685
      OUT_COPY_COUNT3(count, s, temp_s);
1686
      OUT_MIX_COUNT3(mix_count, s);
1687
    }
1688
    else if (color_count > 3 &&
1689
             color_count >= mix_count &&
1690
             color_count >= bicolor_count &&
1691
             color_count >= fill_count &&
1692
             color_count >= fom_count)
1693
    {
1694
      count -= color_count;
1695
      OUT_COPY_COUNT3(count, s, temp_s);
1696
      OUT_COLOR_COUNT3(color_count, s, last_pixel);
1697
    }
1698
    else if (bicolor_count > 3 &&
1699
             bicolor_count >= mix_count &&
1700
             bicolor_count >= color_count &&
1701
             bicolor_count >= fill_count &&
1702
             bicolor_count >= fom_count)
1703
    {
1704
      if ((bicolor_count % 2) == 0)
1705
      {
1706
        count -= bicolor_count;
1707
        OUT_COPY_COUNT3(count, s, temp_s);
1708
        OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2);
1709
      }
1710
      else
1711
      {
1712
        bicolor_count--;
1713
        count -= bicolor_count;
1714
        OUT_COPY_COUNT3(count, s, temp_s);
1715
        OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1);
1716
      }
1717
      count -= bicolor_count;
1718
      OUT_COPY_COUNT3(count, s, temp_s);
1719
      OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2);
1720
    }
1721
    else if (fom_count > 3 &&
1722
             fom_count >= mix_count &&
1723
             fom_count >= color_count &&
1724
             fom_count >= fill_count &&
1725
             fom_count >= bicolor_count)
1726
    {
1727
      count -= fom_count;
1728
      OUT_COPY_COUNT3(count, s, temp_s);
1729
      OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len);
1730
    }
1731
    else
1732
    {
1733
      OUT_COPY_COUNT3(count, s, temp_s);
1734
    }
1735
  }
1473
  return lines_sent;
1736
  return lines_sent;
1474
}
1737
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/xrdp_channel.c (+1 lines)
 Lines 170-175    Link Here 
170
    g_writeln("xrdp_channel_process, channel not found");
170
    g_writeln("xrdp_channel_process, channel not found");
171
    return 1;
171
    return 1;
172
  }
172
  }
173
  rv = 0;
173
  in_uint32_le(s, length);
174
  in_uint32_le(s, length);
174
  in_uint32_le(s, flags);
175
  in_uint32_le(s, flags);
175
  rv = xrdp_channel_call_callback(self, s, channel_id, length, flags);
176
  rv = xrdp_channel_call_callback(self, s, channel_id, length, flags);
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/xrdp_orders.c (-70 / +80 lines)
 Lines 336-345    Link Here 
336
                              char* present_ptr, int present,
336
                              char* present_ptr, int present,
337
                              int present_size)
337
                              int present_size)
338
{
338
{
339
  int move_up_count;
339
  int move_up_count = 0;
340
  int index;
340
  int index = 0;
341
  int size;
341
  int size = 0;
342
  int keep_looking;
342
  int keep_looking = 1;
343
343
344
  move_up_count = 0;
344
  move_up_count = 0;
345
  keep_looking = 1;
345
  keep_looking = 1;
 Lines 527-537    Link Here 
527
                       int cx, int cy, int srcx, int srcy,
527
                       int cx, int cy, int srcx, int srcy,
528
                       int rop, struct xrdp_rect* rect)
528
                       int rop, struct xrdp_rect* rect)
529
{
529
{
530
  int order_flags;
530
  int order_flags = 0;
531
  int vals[12];
531
  int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
532
  int present;
532
  int present = 0;
533
  char* present_ptr;
533
  char* present_ptr = (char *)NULL;
534
  char* order_flags_ptr;
534
  char* order_flags_ptr = (char *)NULL;
535
535
536
  xrdp_orders_check(self, 25);
536
  xrdp_orders_check(self, 25);
537
  self->order_count++;
537
  self->order_count++;
 Lines 996-1008    Link Here 
996
                 struct xrdp_pen* pen,
996
                 struct xrdp_pen* pen,
997
                 struct xrdp_rect* rect)
997
                 struct xrdp_rect* rect)
998
{
998
{
999
  int order_flags;
999
  int order_flags = 0;
1000
  int vals[8];
1000
  int vals[8] = {0, 0, 0, 0, 0, 0, 0, 0};
1001
  int present;
1001
  int present = 0;
1002
  char* present_ptr;
1002
  char* present_ptr = (char *)NULL;
1003
  char* order_flags_ptr;
1003
  char* order_flags_ptr = (char *)NULL;
1004
  struct xrdp_pen blank_pen;
1004
  struct xrdp_pen blank_pen;
1005
1005
1006
  g_memset(&blank_pen,0,sizeof(struct xrdp_pen));
1007
1006
  /* if mix mode or rop are out of range, mstsc build 6000+ will parse the orders
1008
  /* if mix mode or rop are out of range, mstsc build 6000+ will parse the orders
1007
     wrong */
1009
     wrong */
1008
  if ((mix_mode < 1) || (mix_mode > 2)) /* TRANSPARENT(1) or OPAQUE(2) */
1010
  if ((mix_mode < 1) || (mix_mode > 2)) /* TRANSPARENT(1) or OPAQUE(2) */
 Lines 1176-1186    Link Here 
1176
                    int rop, int srcx, int srcy,
1178
                    int rop, int srcx, int srcy,
1177
                    int cache_idx, struct xrdp_rect* rect)
1179
                    int cache_idx, struct xrdp_rect* rect)
1178
{
1180
{
1179
  int order_flags;
1181
  int order_flags = 0;
1180
  int vals[12];
1182
  int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1181
  int present;
1183
  int present = 0;
1182
  char* present_ptr;
1184
  char* present_ptr = (char *)NULL;
1183
  char* order_flags_ptr;
1185
  char* order_flags_ptr = (char *)NULL;
1184
1186
1185
  xrdp_orders_check(self, 30);
1187
  xrdp_orders_check(self, 30);
1186
  self->order_count++;
1188
  self->order_count++;
 Lines 1352-1361    Link Here 
1352
                 int x, int y, char* data, int data_len,
1354
                 int x, int y, char* data, int data_len,
1353
                 struct xrdp_rect* rect)
1355
                 struct xrdp_rect* rect)
1354
{
1356
{
1355
  int order_flags;
1357
  int order_flags = 0;
1356
  int present;
1358
  int present = 0;
1357
  char* present_ptr;
1359
  char* present_ptr = (char *)NULL;
1358
  char* order_flags_ptr;
1360
  char* order_flags_ptr = (char *)NULL;
1359
1361
1360
  xrdp_orders_check(self, 100);
1362
  xrdp_orders_check(self, 100);
1361
  self->order_count++;
1363
  self->order_count++;
 Lines 1546-1559    Link Here 
1546
                            int width, int height, int bpp, char* data,
1548
                            int width, int height, int bpp, char* data,
1547
                            int cache_id, int cache_idx)
1549
                            int cache_id, int cache_idx)
1548
{
1550
{
1549
  int order_flags;
1551
  int order_flags = 0;
1550
  int len;
1552
  int len = 0;
1551
  int bufsize;
1553
  int bufsize = 0;
1552
  int Bpp;
1554
  int Bpp = 0;
1553
  int i;
1555
  int i = 0;
1554
  int j;
1556
  int j = 0;
1555
  int pixel;
1557
  int pixel = 0;
1556
  int e;
1558
  int e = 0;
1557
1559
1558
  if (width > 64)
1560
  if (width > 64)
1559
  {
1561
  {
 Lines 1570-1576    Link Here 
1570
  {
1572
  {
1571
    e = 4 - e;
1573
    e = 4 - e;
1572
  }
1574
  }
1573
  Bpp = (bpp + 7) / 8;
1575
  Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
1574
  bufsize = (width + e) * height * Bpp;
1576
  bufsize = (width + e) * height * Bpp;
1575
  xrdp_orders_check(self, bufsize + 16);
1577
  xrdp_orders_check(self, bufsize + 16);
1576
  self->order_count++;
1578
  self->order_count++;
 Lines 1591-1597    Link Here 
1591
  {
1593
  {
1592
    for (j = 0; j < width; j++)
1594
    for (j = 0; j < width; j++)
1593
    {
1595
    {
1594
      if (Bpp == 3)
1596
      if ((Bpp == 3) || (Bpp == 4))
1595
      {
1597
      {
1596
        pixel = GETPIXEL32(data, j, i, width);
1598
        pixel = GETPIXEL32(data, j, i, width);
1597
        out_uint8(self->out_s, pixel >> 16);
1599
        out_uint8(self->out_s, pixel >> 16);
 Lines 1626-1641    Link Here 
1626
                        int width, int height, int bpp, char* data,
1628
                        int width, int height, int bpp, char* data,
1627
                        int cache_id, int cache_idx)
1629
                        int cache_id, int cache_idx)
1628
{
1630
{
1629
  int order_flags;
1631
  int order_flags = 0;
1630
  int len;
1632
  int len = 0;
1631
  int bufsize;
1633
  int bufsize = 0;
1632
  int Bpp;
1634
  int Bpp = 0;
1633
  int i;
1635
  int i = 0;
1634
  int lines_sending;
1636
  int lines_sending = 0;
1635
  int e;
1637
  int e = 0;
1636
  struct stream* s;
1638
  struct stream* s = NULL;
1637
  struct stream* temp_s;
1639
  struct stream* temp_s = NULL;
1638
  char* p;
1640
  char* p = NULL;
1639
1641
1640
  if (width > 64)
1642
  if (width > 64)
1641
  {
1643
  {
 Lines 1669-1675    Link Here 
1669
    return 1;
1671
    return 1;
1670
  }
1672
  }
1671
  bufsize = (int)(s->p - p);
1673
  bufsize = (int)(s->p - p);
1672
  Bpp = (bpp + 7) / 8;
1674
  Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
1673
  xrdp_orders_check(self, bufsize + 16);
1675
  xrdp_orders_check(self, bufsize + 16);
1674
  self->order_count++;
1676
  self->order_count++;
1675
  order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
1677
  order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
 Lines 1717-1725    Link Here 
1717
                      struct xrdp_font_char* font_char,
1719
                      struct xrdp_font_char* font_char,
1718
                      int font_index, int char_index)
1720
                      int font_index, int char_index)
1719
{
1721
{
1720
  int order_flags;
1722
  int order_flags = 0;
1721
  int datasize;
1723
  int datasize = 0;
1722
  int len;
1724
  int len = 0;
1723
1725
1724
  datasize = FONT_DATASIZE(font_char);
1726
  datasize = FONT_DATASIZE(font_char);
1725
  xrdp_orders_check(self, datasize + 18);
1727
  xrdp_orders_check(self, datasize + 18);
 Lines 1749-1762    Link Here 
1749
                             int width, int height, int bpp, char* data,
1751
                             int width, int height, int bpp, char* data,
1750
                             int cache_id, int cache_idx)
1752
                             int cache_id, int cache_idx)
1751
{
1753
{
1752
  int order_flags;
1754
  int order_flags = 0;
1753
  int len;
1755
  int len = 0;
1754
  int bufsize;
1756
  int bufsize = 0;
1755
  int Bpp;
1757
  int Bpp = 0;
1756
  int i;
1758
  int i = 0;
1757
  int j;
1759
  int j = 0;
1758
  int pixel;
1760
  int pixel = 0;
1759
  int e;
1761
  int e = 0;
1760
1762
1761
  if (width > 64)
1763
  if (width > 64)
1762
  {
1764
  {
 Lines 1773-1779    Link Here 
1773
  {
1775
  {
1774
    e = 4 - e;
1776
    e = 4 - e;
1775
  }
1777
  }
1776
  Bpp = (bpp + 7) / 8;
1778
  Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
1777
  bufsize = (width + e) * height * Bpp;
1779
  bufsize = (width + e) * height * Bpp;
1778
  xrdp_orders_check(self, bufsize + 14);
1780
  xrdp_orders_check(self, bufsize + 14);
1779
  self->order_count++;
1781
  self->order_count++;
 Lines 1795-1801    Link Here 
1795
  {
1797
  {
1796
    for (j = 0; j < width; j++)
1798
    for (j = 0; j < width; j++)
1797
    {
1799
    {
1798
      if (Bpp == 3)
1800
      if (Bpp == 4)
1801
      {
1802
        pixel = GETPIXEL32(data, j, i, width);
1803
        out_uint8(self->out_s, pixel >> 24);
1804
        out_uint8(self->out_s, pixel >> 16);
1805
        out_uint8(self->out_s, pixel >> 8);
1806
        out_uint8(self->out_s, pixel);
1807
      }
1808
      else if (Bpp == 3)
1799
      {
1809
      {
1800
        pixel = GETPIXEL32(data, j, i, width);
1810
        pixel = GETPIXEL32(data, j, i, width);
1801
        out_uint8(self->out_s, pixel >> 16);
1811
        out_uint8(self->out_s, pixel >> 16);
 Lines 1830-1845    Link Here 
1830
                         int width, int height, int bpp, char* data,
1840
                         int width, int height, int bpp, char* data,
1831
                         int cache_id, int cache_idx)
1841
                         int cache_id, int cache_idx)
1832
{
1842
{
1833
  int order_flags;
1843
  int order_flags = 0;
1834
  int len;
1844
  int len = 0;
1835
  int bufsize;
1845
  int bufsize = 0;
1836
  int Bpp;
1846
  int Bpp = 0;
1837
  int i;
1847
  int i = 0;
1838
  int lines_sending;
1848
  int lines_sending = 0;
1839
  int e;
1849
  int e = 0;
1840
  struct stream* s;
1850
  struct stream* s = NULL;
1841
  struct stream* temp_s;
1851
  struct stream* temp_s = NULL;
1842
  char* p;
1852
  char* p = NULL;
1843
1853
1844
  if (width > 64)
1854
  if (width > 64)
1845
  {
1855
  {
 Lines 1873-1879    Link Here 
1873
    return 1;
1883
    return 1;
1874
  }
1884
  }
1875
  bufsize = (int)(s->p - p);
1885
  bufsize = (int)(s->p - p);
1876
  Bpp = (bpp + 7) / 8;
1886
  Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
1877
  xrdp_orders_check(self, bufsize + 14);
1887
  xrdp_orders_check(self, bufsize + 14);
1878
  self->order_count++;
1888
  self->order_count++;
1879
  order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
1889
  order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
 Lines 1904-1911    Link Here 
1904
xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height,
1914
xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height,
1905
                       int bpp, int type, int size, char* data, int cache_id)
1915
                       int bpp, int type, int size, char* data, int cache_id)
1906
{
1916
{
1907
  int order_flags;
1917
  int order_flags = 0;
1908
  int len;
1918
  int len = 0;
1909
1919
1910
  xrdp_orders_check(self, size + 12);
1920
  xrdp_orders_check(self, size + 12);
1911
  self->order_count++;
1921
  self->order_count++;
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/xrdp_rdp.c (-40 / +161 lines)
 Lines 20-26    Link Here 
20
20
21
*/
21
*/
22
22
23
#include <stdlib.h>
24
#ifdef _XRDP_ENABLE_I18N_
25
#include <wchar.h>
26
#include <iconv.h>
27
#endif
23
#include "libxrdp.h"
28
#include "libxrdp.h"
29
#include "dbg.h"
24
30
25
/* some compilers need unsigned char to avoid warnings */
31
/* some compilers need unsigned char to avoid warnings */
26
static tui8 g_unknown1[172] =
32
static tui8 g_unknown1[172] =
 Lines 57-69    Link Here 
57
static int APP_CC
63
static int APP_CC
58
xrdp_rdp_read_config(struct xrdp_client_info* client_info)
64
xrdp_rdp_read_config(struct xrdp_client_info* client_info)
59
{
65
{
60
  int index;
66
  int index = 0;
61
  struct list* items;
67
  struct list* items = (struct list *)NULL;
62
  struct list* values;
68
  struct list* values = (struct list *)NULL;
63
  char* item;
69
  char* item = (char *)NULL;
64
  char* value;
70
  char* value = (char *)NULL;
65
  char cfg_file[256];
71
  char cfg_file[256];
66
72
73
  /* initialize (zero out) local variables: */
74
  g_memset(cfg_file,0,sizeof(char) * 256);
75
67
  items = list_create();
76
  items = list_create();
68
  items->auto_free = 1;
77
  items->auto_free = 1;
69
  values = list_create();
78
  values = list_create();
 Lines 124-130    Link Here 
124
struct xrdp_rdp* APP_CC
133
struct xrdp_rdp* APP_CC
125
xrdp_rdp_create(struct xrdp_session* session, int sck)
134
xrdp_rdp_create(struct xrdp_session* session, int sck)
126
{
135
{
127
  struct xrdp_rdp* self;
136
  struct xrdp_rdp* self = (struct xrdp_rdp *)NULL;
128
137
129
  DEBUG(("in xrdp_rdp_create"));
138
  DEBUG(("in xrdp_rdp_create"));
130
  self = (struct xrdp_rdp*)g_malloc(sizeof(struct xrdp_rdp), 1);
139
  self = (struct xrdp_rdp*)g_malloc(sizeof(struct xrdp_rdp), 1);
 Lines 187-196    Link Here 
187
int APP_CC
196
int APP_CC
188
xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code)
197
xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code)
189
{
198
{
190
  int error;
199
  int error = 0;
191
  int len;
200
  int len = 0;
192
  int pdu_code;
201
  int pdu_code = 0;
193
  int chan;
202
  int chan = 0;
194
203
195
  DEBUG(("in xrdp_rdp_recv"));
204
  DEBUG(("in xrdp_rdp_recv"));
196
  if (s->next_packet == 0 || s->next_packet >= s->end)
205
  if (s->next_packet == 0 || s->next_packet >= s->end)
 Lines 226-241    Link Here 
226
  {
235
  {
227
    s->p = s->next_packet;
236
    s->p = s->next_packet;
228
  }
237
  }
229
  if (!s_check_rem(s, 6))
238
  in_uint16_le(s, len);
239
  if (len == 0x8000)
230
  {
240
  {
231
    s->next_packet = 0;
241
    s->next_packet += 8;
232
    *code = 0;
242
    *code = 0;
233
    DEBUG(("out xrdp_rdp_recv"));
243
    DEBUG(("out xrdp_rdp_recv"));
234
    len = (int)(s->end - s->p);
235
    g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len);
236
    return 0;
244
    return 0;
237
  }
245
  }
238
  in_uint16_le(s, len);
239
  in_uint16_le(s, pdu_code);
246
  in_uint16_le(s, pdu_code);
240
  *code = pdu_code & 0xf;
247
  *code = pdu_code & 0xf;
241
  in_uint8s(s, 2); /* mcs user id */
248
  in_uint8s(s, 2); /* mcs user id */
 Lines 248-254    Link Here 
248
int APP_CC
255
int APP_CC
249
xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type)
256
xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type)
250
{
257
{
251
  int len;
258
  int len = 0;
252
259
253
  DEBUG(("in xrdp_rdp_send"));
260
  DEBUG(("in xrdp_rdp_send"));
254
  s_pop_layer(s, rdp_hdr);
261
  s_pop_layer(s, rdp_hdr);
 Lines 270-276    Link Here 
270
xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s,
277
xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s,
271
                   int data_pdu_type)
278
                   int data_pdu_type)
272
{
279
{
273
  int len;
280
  int len = 0;
274
281
275
  DEBUG(("in xrdp_rdp_send_data"));
282
  DEBUG(("in xrdp_rdp_send_data"));
276
  s_pop_layer(s, rdp_hdr);
283
  s_pop_layer(s, rdp_hdr);
 Lines 298-304    Link Here 
298
int APP_CC
305
int APP_CC
299
xrdp_rdp_send_data_update_sync(struct xrdp_rdp* self)
306
xrdp_rdp_send_data_update_sync(struct xrdp_rdp* self)
300
{
307
{
301
  struct stream* s;
308
  struct stream * s = (struct stream *)NULL;
302
309
303
  make_stream(s);
310
  make_stream(s);
304
  init_stream(s, 8192);
311
  init_stream(s, 8192);
 Lines 327-351    Link Here 
327
static int APP_CC
334
static int APP_CC
328
xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp* self)
335
xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp* self)
329
{
336
{
330
  struct stream* p;
337
  struct stream* p = (struct stream *)NULL;
331
  int i;
338
  int i = 0;
339
  char str1[16];
340
  char str2[32];
341
  wint_t wstr1[16];
342
  wint_t wstr2[32];
343
  uint8_t hi = 0x0000;
344
  uint8_t lo = 0x0000;
345
  uint16_t ud_length = 0x0000;
346
  uint16_t ud_type = 0x0000;
347
348
  MDBGLOG("sound","INFO\t[%s()]: !!!! xrdp_rdp_parse_client_mcs_data() called !!!! ",__func__);
349
350
  self->client_info.version = 0x00000000;
351
  self->client_info.colorDepth = 0x0000;
352
  self->client_info.highColorDepth = 0x0000;
353
  self->client_info.postBeta2ColorDepth = 0x0000;
354
  self->client_info.earlyCapabilityFlags = 0x0000;
355
  self->client_info.supportedColorDepths = 0x0000;
356
  self->client_info.keyboardLayout = 0x00000000;
357
  self->client_info.keyboardType = 0x00000000;
358
  self->client_info.keyboardSubType = 0x00000000;
359
  self->client_info.keyboardFunctionKey = 0x00000000;
360
  self->client_info.clientBuild = 0x00000000;
361
  self->client_info.clientProductId = 0x0000;
362
  self->client_info.connectionType = 0x00;
363
  self->client_info.serialNumber = 0x00000000;
364
  self->client_info.serverSelectedProtocol = 0x00000000;
365
  memset((void *)(self->client_info.clientName),(int)0x0000,(size_t)(sizeof(uint16_t) * 16));
366
  memset((void *)(self->client_info.imeFileName),(int)0x00000000,(size_t)(sizeof(uint16_t) * 32));
367
  memset((void *)(self->client_info.clientDigProductId),(int)0x00,(size_t)(sizeof(uint8_t) * 64));
368
  memset(str1,0,sizeof(char) * 16);
369
  memset(str2,0,sizeof(char) * 32);
370
  memset(wstr1,0,sizeof(wint_t) * 16);
371
  memset(wstr2,0,sizeof(wint_t) * 32);
332
372
333
  p = &(self->sec_layer->client_mcs_data);
373
  p = &(self->sec_layer->client_mcs_data);
334
  p->p = p->data;
374
  p->p = p->data;
335
  in_uint8s(p, 31);
375
  in_uint8s(p, 23);
376
  in_uint16_le(p, ud_type);
377
  in_uint16_le(p, ud_length);
378
  in_uint32_le(p, self->client_info.version);
336
  in_uint16_le(p, self->client_info.width);
379
  in_uint16_le(p, self->client_info.width);
337
  in_uint16_le(p, self->client_info.height);
380
  in_uint16_le(p, self->client_info.height);
338
  in_uint8s(p, 120);
381
  in_uint16_le(p, self->client_info.colorDepth);
339
  self->client_info.bpp = 8;
340
  in_uint16_le(p, i);
382
  in_uint16_le(p, i);
341
  switch (i)
383
  in_uint32_le(p, self->client_info.keyboardLayout);
384
  in_uint32_le(p, self->client_info.clientBuild);
385
  /* read in the "clientName" field: (up to 15 unicode characters plus a terminating null character) */
386
  for (i = 0; i < 16; i++) {
387
    in_uint16_le(p, self->client_info.clientName[i]);
388
    hi = self->client_info.clientName[i] >> 8;
389
    lo = self->client_info.clientName[i] & 0x00ff;
390
    wstr1[i] = (wint_t)(utf16_to_utf32(hi, lo));
391
    hi = 0;
392
    lo = 0;
393
  }
394
  in_uint32_le(p, self->client_info.keyboardType);
395
  in_uint32_le(p, self->client_info.keyboardSubType);
396
  in_uint32_le(p, self->client_info.keyboardFunctionKey);
397
  /* read in the "imeFileName" field: (up to 31 unicode characters plus a terminating NULL) */
398
  for (i = 0; i < 32; i++) {
399
    in_uint16_le(p, self->client_info.imeFileName[i]);
400
    hi = self->client_info.imeFileName[i] >> 8;
401
    lo = self->client_info.imeFileName[i] & 0x00ff;
402
    wstr2[i] = (wint_t)(utf16_to_utf32(hi, lo));
403
    hi = 0;
404
    lo = 0;
405
  }
406
  in_uint16_le(p, self->client_info.postBeta2ColorDepth);
407
  in_uint16_le(p, self->client_info.clientProductId);
408
  in_uint32_le(p, self->client_info.serialNumber);
409
  in_uint16_le(p, self->client_info.highColorDepth);
410
  in_uint16_le(p, self->client_info.supportedColorDepths);
411
  in_uint16_le(p, self->client_info.earlyCapabilityFlags);
412
  if ((self->client_info.earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE) != 0x0000) {
413
    in_uint8a(p, self->client_info.clientDigProductId, 64);
414
    in_uint8(p, self->client_info.connectionType);
415
  }
416
417
  wcstombs(str1, (const wchar_t * restrict)(self->client_info.clientName), 16);
418
  wcstombs(str2, (const wchar_t * restrict)(self->client_info.imeFileName), 32);
419
  //MDBGLOG("sound","\n\n$$$$\n postBeta2ColorDepth=%8.8x;\n highColorDepth=%d;\n supportedColorDepths=%d;\n earlyCapabilityFlags=%d;\n keyboardType=%d;\n keyboardLayout=%d;\n colorDepth=%8.8x;\n connectionType=%d;\n clientName=%s;\n imeFileName=%s;\n version=%8.8x;\n length=%d;\n",self->client_info.postBeta2ColorDepth, self->client_info.highColorDepth, self->client_info.supportedColorDepths, self->client_info.earlyCapabilityFlags, self->client_info.keyboardType, self->client_info.keyboardLayout, self->client_info.colorDepth, self->client_info.connectionType, str1, str2, (unsigned int)(self->client_info.version), ud_length);
420
421
  self->client_info.bpp = 8;
422
  switch (self->client_info.postBeta2ColorDepth)
342
  {
423
  {
424
    case 0xca00:
425
      self->client_info.bpp = 4;
426
      break;
343
    case 0xca01:
427
    case 0xca01:
344
      in_uint8s(p, 6);
428
      if (self->client_info.highColorDepth > 8)
345
      in_uint8(p, i);
346
      if (i > 8)
347
      {
429
      {
348
        self->client_info.bpp = i;
430
        self->client_info.bpp = self->client_info.highColorDepth;
349
      }
431
      }
350
      break;
432
      break;
351
    case 0xca02:
433
    case 0xca02:
 Lines 358-367    Link Here 
358
      self->client_info.bpp = 24;
440
      self->client_info.bpp = 24;
359
      break;
441
      break;
360
  }
442
  }
443
  if ((self->client_info.earlyCapabilityFlags & RNS_UD_CS_WANT_32BPP_SESSION) != 0x0000) {
444
    self->client_info.bpp = 32;
445
  }
446
361
  p->p = p->data;
447
  p->p = p->data;
362
  DEBUG(("client width %d, client height %d bpp %d",
448
  //MDBGLOG("sound","client width %d, client height %d bpp %d",
363
         self->client_info.width, self->client_info.height,
449
  //       self->client_info.width, self->client_info.height,
364
         self->client_info.bpp));
450
  //       self->client_info.bpp);
451
  //DEBUG(("client width %d, client height %d bpp %d",
452
  //       self->client_info.width, self->client_info.height,
453
  //       self->client_info.bpp));
365
  return 0;
454
  return 0;
366
}
455
}
367
456
 Lines 423-434    Link Here 
423
  caps_count++;
512
  caps_count++;
424
  out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */
513
  out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */
425
  out_uint16_le(s, RDP_CAPLEN_GENERAL); /* 24(0x18) */
514
  out_uint16_le(s, RDP_CAPLEN_GENERAL); /* 24(0x18) */
426
  out_uint16_le(s, 1); /* OS major type */
515
  //out_uint16_le(s, 1); /* OS major type */
427
  out_uint16_le(s, 3); /* OS minor type */
516
  //out_uint16_le(s, 3); /* OS minor type */
517
  out_uint16_le(s, OSMAJORTYPE_UNIX); /* OS major type */
518
  out_uint16_le(s, TS_OSMINORTYPE_NATIVE_XSERVER); /* OS minor type */
428
  out_uint16_le(s, 0x200); /* Protocol version */
519
  out_uint16_le(s, 0x200); /* Protocol version */
429
  out_uint16_le(s, 0); /* pad */
520
  out_uint16_le(s, 0); /* pad */
430
  out_uint16_le(s, 0); /* Compression types */
521
  out_uint16_le(s, 0); /* Compression types */
431
  out_uint16_le(s, 0); /* pad use 0x40d for rdp packets, 0 for not */
522
  //out_uint16_le(s, 0); /* pad use 0x40d for rdp packets, 0 for not */
523
  out_uint16_le(s, 0x40d); /* pad use 0x40d for rdp packets, 0 for not */
432
  out_uint16_le(s, 0); /* Update capability */
524
  out_uint16_le(s, 0); /* Update capability */
433
  out_uint16_le(s, 0); /* Remote unshare capability */
525
  out_uint16_le(s, 0); /* Remote unshare capability */
434
  out_uint16_le(s, 0); /* Compression level */
526
  out_uint16_le(s, 0); /* Compression level */
 Lines 487-496    Link Here 
487
  out_uint8(s, 0); /* multi dest blt */
579
  out_uint8(s, 0); /* multi dest blt */
488
  out_uint8(s, 0); /* multi pat blt */
580
  out_uint8(s, 0); /* multi pat blt */
489
  out_uint8(s, 0); /* multi screen blt */
581
  out_uint8(s, 0); /* multi screen blt */
490
  out_uint8(s, 0); /* multi rect */
582
  out_uint8(s, 1); /* multi rect */
491
  out_uint8(s, 0); /* fast index */
583
  out_uint8(s, 0); /* fast index */
492
  out_uint8(s, 0); /* polygon */
584
  out_uint8(s, 0); /* polygonSC ([MS-RDPEGDI], 2.2.2.2.1.1.2.16) */
493
  out_uint8(s, 0); /* polygon */
585
  out_uint8(s, 0); /* polygonCB ([MS-RDPEGDI], 2.2.2.2.1.1.2.17) */
494
  out_uint8(s, 0); /* polyline */
586
  out_uint8(s, 0); /* polyline */
495
  out_uint8(s, 0); /* unused */
587
  out_uint8(s, 0); /* unused */
496
  out_uint8(s, 0); /* fast glyph */
588
  out_uint8(s, 0); /* fast glyph */
 Lines 644-654    Link Here 
644
xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s,
736
xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s,
645
                              int len)
737
                              int len)
646
{
738
{
647
  int Bpp;
739
  int Bpp = 0;
648
  int i;
740
  int i = 0;
649
741
650
  self->client_info.bitmap_cache_version = 2;
742
  self->client_info.bitmap_cache_version = 2;
651
  Bpp = (self->client_info.bpp + 7) / 8;
743
  Bpp = (self->client_info.bpp == 32) ? 3 : (self->client_info.bpp + 7) / 8;
652
  in_uint16_le(s, i);
744
  in_uint16_le(s, i);
653
  self->client_info.bitmap_cache_persist_enable = i;
745
  self->client_info.bitmap_cache_persist_enable = i;
654
  in_uint8s(s, 2); /* number of caches in set, 3 */
746
  in_uint8s(s, 2); /* number of caches in set, 3 */
 Lines 1155-1157    Link Here 
1155
  DEBUG(("out xrdp_rdp_send_deactive"));
1247
  DEBUG(("out xrdp_rdp_send_deactive"));
1156
  return 0;
1248
  return 0;
1157
}
1249
}
1250
1251
UTF32 utf16_to_utf32(UTF16 lead, UTF16 trail) {
1252
  const UTF32 SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00;
1253
  UTF32 rv = 0x00000000;
1254
1255
  // computations
1256
  rv = (lead << 10) + trail + SURROGATE_OFFSET;
1257
1258
  return rv;
1259
}
1260
1261
UTF16 * utf32_to_utf16(UTF32 codepoint) {
1262
  const UTF32 LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
1263
  UTF16 * rv = (UTF16 *)NULL;
1264
  UTF16 lead = 0x0000;
1265
  UTF16 trail = 0x0000;
1266
1267
  rv = (UTF16 *)malloc(sizeof(UTF16) * 2);
1268
  rv[0] = 0x0000;
1269
  rv[1] = 0x0000;
1270
1271
  // computations
1272
  lead = LEAD_OFFSET + (codepoint >> 10);
1273
  trail = 0xDC00 + (codepoint & 0x3FF);
1274
  rv[0] = lead;
1275
  rv[1] = trail;
1276
1277
  return rv;
1278
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/libxrdp/xrdp_sec.c (-49 / +77 lines)
 Lines 303-356    Link Here 
303
static int APP_CC
303
static int APP_CC
304
xrdp_sec_process_logon_info(struct xrdp_sec* self, struct stream* s)
304
xrdp_sec_process_logon_info(struct xrdp_sec* self, struct stream* s)
305
{
305
{
306
  int flags;
306
  int flags = 0;
307
  int len_domain;
307
  int len_domain = 0;
308
  int len_user;
308
  int len_user = 0;
309
  int len_password;
309
  int len_password = 0;
310
  int len_program;
310
  int len_program = 0;
311
  int len_directory;
311
  int len_directory = 0;
312
  int len_ip;
312
  int len_ip = 0;
313
  int len_dll;
313
  int len_dll = 0;
314
  int tzone;
314
  int tzone = 0;
315
  char tmpdata[256];
315
  char tmpdata[256];
316
316
317
  in_uint8s(s, 4);
317
  /* initialize (zero out) local variables */
318
  in_uint32_le(s, flags);
318
  g_memset(tmpdata,0,sizeof(char)*256);
319
  DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags));
319
  self->rdp_layer->client_info.clientAddress = (uint8_t *)g_malloc(sizeof(uint8_t) * 511,1);
320
  self->rdp_layer->client_info.clientDir = (uint8_t *)g_malloc(sizeof(uint8_t) * 511,1);
321
322
  //in_uint8s(s, 4);		/* skip over "CodePage" field */
323
  in_uint32_le(s, self->rdp_layer->client_info.CodePage);
324
  in_uint32_le(s, self->rdp_layer->client_info.flags);
325
  DEBUG(("in xrdp_sec_process_logon_info flags $%x", self->rdp_layer->client_info.flags));
320
  /* this is the first test that the decrypt is working */
326
  /* this is the first test that the decrypt is working */
321
  if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */
327
  if ((self->rdp_layer->client_info.flags & (INFO_MOUSE | INFO_DISABLECTRLALTDEL | INFO_UNICODE | INFO_MAXIMIZESHELL)) != (INFO_MOUSE | INFO_DISABLECTRLALTDEL | INFO_UNICODE | INFO_MAXIMIZESHELL)) /* 0x33 */
322
  {                                                   /* must be or error */
328
  {                                                   /* must be or error */
323
    DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error"));
329
    DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error"));
324
    return 1;
330
    return 1;
325
  }
331
  }
326
  if (flags & RDP_LOGON_LEAVE_AUDIO)
332
  if (self->rdp_layer->client_info.flags & INFO_REMOTECONSOLEAUDIO)
327
  {
333
  {
328
    self->rdp_layer->client_info.sound_code = 1;
334
    self->rdp_layer->client_info.sound_code = 1;
329
    DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found"));
335
    DEBUG(("flag INFO_REMOTECONSOLEAUDIO found"));
330
  }
336
  }
331
  if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce))
337
  if ((self->rdp_layer->client_info.flags & INFO_AUTOLOGON) && (!self->rdp_layer->client_info.is_mce))
332
  /* todo, for now not allowing autologon and mce both */
338
  /* todo, for now not allowing autologon and mce both */
333
  {
339
  {
334
    self->rdp_layer->client_info.rdp_autologin = 1;
340
    self->rdp_layer->client_info.rdp_autologin = 1;
335
    DEBUG(("flag RDP_LOGON_AUTO found"));
341
    DEBUG(("flag INFO_AUTOLOGON found"));
336
  }
342
  }
337
  if (flags & RDP_COMPRESSION)
343
  if (self->rdp_layer->client_info.flags & INFO_COMPRESSION)
338
  {
344
  {
339
    self->rdp_layer->client_info.rdp_compression = 1;
345
    self->rdp_layer->client_info.rdp_compression = 1;
340
    DEBUG(("flag RDP_COMPRESSION found"));
346
    DEBUG(("flag INFO_COMPRESSION found"));
341
  }
347
  }
342
  in_uint16_le(s, len_domain);
348
  in_uint16_le(s, len_domain);
349
  if (len_domain > 511) {
350
    DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511"));
351
    return 1;
352
  }
343
  in_uint16_le(s, len_user);
353
  in_uint16_le(s, len_user);
354
  if (len_domain > 511) {
355
    DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511"));
356
    return 1;
357
  }
344
  in_uint16_le(s, len_password);
358
  in_uint16_le(s, len_password);
359
  if (len_password > 511) {
360
    DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511"));
361
    return 1;
362
  }
345
  in_uint16_le(s, len_program);
363
  in_uint16_le(s, len_program);
364
  if (len_program > 511) {
365
    DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511"));
366
    return 1;
367
  }
346
  in_uint16_le(s, len_directory);
368
  in_uint16_le(s, len_directory);
347
  /* todo, we should error out in any of the above lengths are > 512 */
369
  if (len_directory > 511) {
370
    DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511"));
371
    return 1;
372
  }
373
  /* todo, we should error out if any of the above lengths are > 512 */
348
  /* to avoid buffer overruns */
374
  /* to avoid buffer overruns */
349
  unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255);
375
  unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255);
350
  DEBUG(("domain %s", self->rdp_layer->client_info.domain));
376
  DEBUG(("domain %s", self->rdp_layer->client_info.domain));
351
  unicode_in(s, len_user, self->rdp_layer->client_info.username, 255);
377
  unicode_in(s, len_user, self->rdp_layer->client_info.username, 255);
352
  DEBUG(("username %s", self->rdp_layer->client_info.username));
378
  DEBUG(("username %s", self->rdp_layer->client_info.username));
353
  if (flags & RDP_LOGON_AUTO)
379
  if (self->rdp_layer->client_info.flags & RDP_LOGON_AUTO)
354
  {
380
  {
355
    unicode_in(s, len_password, self->rdp_layer->client_info.password, 255);
381
    unicode_in(s, len_password, self->rdp_layer->client_info.password, 255);
356
    DEBUG(("flag RDP_LOGON_AUTO found"));
382
    DEBUG(("flag RDP_LOGON_AUTO found"));
 Lines 363-383    Link Here 
363
  DEBUG(("program %s", self->rdp_layer->client_info.program));
389
  DEBUG(("program %s", self->rdp_layer->client_info.program));
364
  unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255);
390
  unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255);
365
  DEBUG(("directory %s", self->rdp_layer->client_info.directory));
391
  DEBUG(("directory %s", self->rdp_layer->client_info.directory));
366
  if (flags & RDP_LOGON_BLOB)
392
  if (self->rdp_layer->client_info.flags & RDP_LOGON_BLOB)
367
  {
393
  {
368
    in_uint8s(s, 2);                                    /* unknown */
394
    in_uint16_le(s,self->rdp_layer->client_info.clientAddressFamily);	/* network address family (either CI_AF_INET or CI_AF_INET6) */
369
    in_uint16_le(s, len_ip);
395
    in_uint16_le(s, self->rdp_layer->client_info.cbClientAddress);
370
    unicode_in(s, len_ip - 2, tmpdata, 255);
396
    unicode_in(s, self->rdp_layer->client_info.cbClientAddress - 2, self->rdp_layer->client_info.clientAddress, 255);
371
    in_uint16_le(s, len_dll);
397
    in_uint16_le(s, self->rdp_layer->client_info.cbClientDir);
372
    unicode_in(s, len_dll - 2, tmpdata, 255);
398
    unicode_in(s, self->rdp_layer->client_info.cbClientDir - 2, self->rdp_layer->client_info.clientDir, 255);
373
    in_uint32_le(s, tzone);                             /* len of timetone */
399
    in_uint8s(s, 148);					/* skip over timezone */
374
    in_uint8s(s, 62);                                   /* skip */
400
    in_uint32_le(s, self->rdp_layer->client_info.clientSessionId);
375
    in_uint8s(s, 22);                                   /* skip misc. */
376
    in_uint8s(s, 62);                                   /* skip */
377
    in_uint8s(s, 26);                                   /* skip stuff */
378
    in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags);
401
    in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags);
402
    in_uint16_le(s, self->rdp_layer->client_info.cbAutoReconnectLen);
403
    unicode_in(s, self->rdp_layer->client_info.cbAutoReconnectLen - 2, self->rdp_layer->client_info.autoReconnectCookie, 255);
379
  }
404
  }
380
  DEBUG(("out xrdp_sec_process_logon_info"));
405
  //MDBGLOG("sound","\n ------\n\n * clientAddress: %s\n * clientDir: %s\n",self->rdp_layer->client_info.clientAddress,self->rdp_layer->client_info.clientDir);
406
  //DEBUG(("out xrdp_sec_process_logon_info"));
381
  return 0;
407
  return 0;
382
}
408
}
383
409
 Lines 386-392    Link Here 
386
static int APP_CC
412
static int APP_CC
387
xrdp_sec_send_lic_initial(struct xrdp_sec* self)
413
xrdp_sec_send_lic_initial(struct xrdp_sec* self)
388
{
414
{
389
  struct stream* s;
415
  struct stream* s = (struct stream *)NULL;
390
416
391
  make_stream(s);
417
  make_stream(s);
392
  init_stream(s, 8192);
418
  init_stream(s, 8192);
 Lines 725-734    Link Here 
725
int APP_CC
751
int APP_CC
726
xrdp_sec_process_mcs_data(struct xrdp_sec* self)
752
xrdp_sec_process_mcs_data(struct xrdp_sec* self)
727
{
753
{
728
  struct stream* s;
754
  struct stream* s = (struct stream *)NULL;
729
  char* hold_p;
755
  char* hold_p = (char *)NULL;
730
  int tag;
756
  int tag = 0;
731
  int size;
757
  int size = 0;
732
758
733
  s = &self->client_mcs_data;
759
  s = &self->client_mcs_data;
734
  /* set p to beginning */
760
  /* set p to beginning */
 Lines 861-873    Link Here 
861
static void APP_CC
887
static void APP_CC
862
xrdp_sec_in_mcs_data(struct xrdp_sec* self)
888
xrdp_sec_in_mcs_data(struct xrdp_sec* self)
863
{
889
{
864
  struct stream* s;
890
  struct stream* s = (struct stream *)NULL;
865
  struct xrdp_client_info* client_info;
891
  struct xrdp_client_info* client_info = (struct xrdp_client_info *)NULL;
866
  int index;
892
  int index = 0;
867
  char c;
893
  char c = 0;
868
894
869
  client_info = &self->rdp_layer->client_info;
895
  client_info = &(self->rdp_layer->client_info);
870
  s = &self->client_mcs_data;
896
  s = &(self->client_mcs_data);
871
  /* get hostname, its unicode */
897
  /* get hostname, its unicode */
872
  s->p = s->data;
898
  s->p = s->data;
873
  in_uint8s(s, 47);
899
  in_uint8s(s, 47);
 Lines 896-908    Link Here 
896
int APP_CC
922
int APP_CC
897
xrdp_sec_incoming(struct xrdp_sec* self)
923
xrdp_sec_incoming(struct xrdp_sec* self)
898
{
924
{
899
  struct list* items;
925
  struct list* items = NULL;
900
  struct list* values;
926
  struct list* values = NULL;
901
  int index;
927
  int index = 0;
902
  char* item;
928
  char* item = NULL;
903
  char* value;
929
  char* value = NULL;
904
  char key_file[256];
930
  char key_file[256];
905
931
932
  g_memset(key_file,0,sizeof(char)*256);
933
906
  DEBUG((" in xrdp_sec_incoming"));
934
  DEBUG((" in xrdp_sec_incoming"));
907
  g_random(self->server_random, 32);
935
  g_random(self->server_random, 32);
908
  items = list_create();
936
  items = list_create();
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/drivers/rdp.c (+1617 lines)
Line 0    Link Here 
1
#include <linux/rdp.h>
2
#include <linux/tty_flip.h>
3
4
static struct rdp_tty * g_tty_driver = (struct rdp_tty *)NULL;
5
static DEFINE_MUTEX(g_tty_driver_mutex);
6
7
static struct mutex * p_tty_mutex = (struct mutex *)NULL;
8
static struct rdp_port g_ports[MAX_PORT];
9
static int g_port_count = 0;
10
11
static struct mutex g_write_mutex = {};
12
static struct mutex * p_write_mutex = (struct mutex *)NULL;
13
14
static struct rdp_cmd *			g_cmds[16];
15
static struct rdp_cmd *			g_pend[16];
16
static struct rdp_irq_entry *		g_read[16];
17
static struct rdp_write_entry *		g_write[16];
18
static completed_cmd_list_t *		g_compl[16];
19
static struct rdp_cb_entry *		g_cb[16];
20
static int g_initialized = 0;
21
22
static int rdp_receive(struct rdp_port *, int, int, char *);
23
static void __cb_enq(struct rdp_cb_entry *);
24
static void cb_enq(struct rdp_cb_entry *);
25
static struct rdp_cb_entry * __cb_deq(struct rdp_cb_entry **);
26
static struct rdp_cb_entry * cb_deq(struct rdp_cb_entry **);
27
static void read_enq(struct rdp_irq_entry *);
28
static struct rdp_irq_entry * read_deq(struct rdp_irq_entry **);
29
static void write_enq(struct rdp_write_entry *);
30
static struct rdp_write_entry * write_deq(struct rdp_write_entry **);
31
static struct list_head * compl_enq(completed_cmd_list_t *);
32
static completed_cmd_list_t * __compl_deq(completed_cmd_list_t **);
33
static completed_cmd_list_t * compl_deq(completed_cmd_list_t **);
34
35
#define Q_NAME  "rdp_workq"
36
static void rdp_cmdw_handler(struct work_struct *);
37
static struct workqueue_struct * g_cmdq = (struct workqueue_struct *)NULL;
38
static DECLARE_WORK(g_cmdw, rdp_cmdw_handler);
39
40
#define COMPLQ_NAME  "rdp_compq"
41
static void rdp_complw_handler(struct work_struct *);
42
static struct workqueue_struct * g_complq = (struct workqueue_struct *)NULL;
43
//static DECLARE_DELAYED_WORK(g_complw, rdp_complw_handler);
44
static DECLARE_WORK(g_complw, rdp_complw_handler);
45
46
#define READQ_NAME  "rdp_readq"
47
static void rdp_readw_handler(struct work_struct *);
48
static struct workqueue_struct * g_readq = (struct workqueue_struct *)NULL;
49
static DECLARE_WORK(g_readw, rdp_readw_handler);
50
51
#define WRITEQ_NAME  "rdp_writeq"
52
static void rdp_writew_handler(struct work_struct *);
53
static struct workqueue_struct * g_writeq = (struct workqueue_struct *)NULL;
54
static DECLARE_WORK(g_writew, rdp_writew_handler);
55
56
static struct list_head * p_enq(struct rdp_cmd *);
57
58
static const char * cmdarray[] = CMD_TO_STRING_ARRAY_DEF;
59
60
static LIST_HEAD(rdp_completed_cmds);
61
static DEFINE_SPINLOCK(rdp_completed_cmds_lock);
62
63
static LIST_HEAD(rdp_read_list);
64
static DEFINE_SPINLOCK(rdp_read_lock);
65
static LIST_HEAD(rdp_write_list);
66
static DEFINE_SPINLOCK(rdp_write_lock);
67
68
static DEFINE_MUTEX(g_cb_mutex);
69
static struct mutex * p_cb_mutex = (struct mutex *)NULL;
70
71
72
/***
73
 ***	Netlink Connection ("cn") functions
74
 ***/
75
76
static struct rdp_family rdp_default_family = {};
77
78
static DEFINE_SPINLOCK(rdp_flock);
79
static DEFINE_SPINLOCK(rdp_cmd_lock);
80
static LIST_HEAD(rdp_families);
81
static LIST_HEAD(rdp_outbound_cmd_list);
82
static LIST_HEAD(rdp_pending_cmd_list);
83
84
#define CBQ_NAME  "rdp_cbq"
85
static void rdp_cn_callback_bh(CBARGS);
86
static LIST_HEAD(rdp_cb_list);
87
static DEFINE_SPINLOCK(rdp_cb_lock);
88
static void rdp_cbw_handler(struct work_struct *);
89
static struct workqueue_struct * g_cbq = (struct workqueue_struct *)NULL;
90
static DECLARE_WORK(g_cbw, rdp_cbw_handler);
91
92
93
static void rdp_cn_callback(CBARGS) {
94
      struct rdp_cb_entry * cb_entry = (struct rdp_cb_entry *)NULL;
95
      unsigned char * buf = (unsigned char *)NULL;
96
      unsigned char * sbuf = (unsigned char *)NULL;
97
      struct cn_msg * lmsg = (struct cn_msg *)NULL;
98
99
      if (imsg == NULL || g_initialized < 1) {
100
	goto end;
101
      }
102
      cb_entry = (struct rdp_cb_entry *)kzalloc((sizeof(struct rdp_cb_entry) + imsg->len + 1), GFP_ATOMIC);
103
      if (cb_entry == NULL) {
104
	goto end;
105
      }
106
      else {
107
	if (parms != NULL) {
108
	  memcpy(&(cb_entry->parms), parms, sizeof(struct netlink_skb_parms));
109
	}
110
	lmsg = &(cb_entry->imsg);
111
	buf = (unsigned char *)(lmsg + 1);
112
	sbuf = (unsigned char *)(imsg + 1);
113
//	memcpy(&(cb_entry->imsg), imsg, (sizeof(struct cn_msg) + imsg->len));
114
	memcpy(lmsg, imsg, sizeof(struct cn_msg));
115
	memcpy(buf, sbuf, imsg->len);
116
      }
117
118
      cb_enq(cb_entry);
119
      queue_work(g_cbq, &g_cbw);
120
121
  end:;
122
}
123
124
static void rdp_cbw_handler(struct work_struct * work) {
125
    struct rdp_cb_entry * cb = (struct rdp_cb_entry *)NULL;
126
127
    if (work == NULL || g_initialized < 1 || p_cb_mutex == NULL) {
128
      goto end;
129
    }
130
    mutex_lock(p_cb_mutex);
131
    cb_deq(&cb);
132
    if (cb != NULL) {
133
      rdp_cn_callback_bh(&(cb->imsg), &(cb->parms));
134
    }
135
    mutex_unlock(p_cb_mutex);
136
137
  end:;
138
}
139
140
static void rdp_cn_callback_bh(CBARGS) {
141
  unsigned long flags;
142
  int found = 0;
143
  int mlen = 0;
144
  int i = 0;
145
  int lcompleted = 0;
146
  uint8_t mtype = 0x00;
147
  int status = 0;
148
  struct cn_msg * msg = (struct cn_msg *)imsg;
149
  rdp_netlink_msg * m = (rdp_netlink_msg *)(msg + 1);
150
  struct device * gdev = (struct device *)NULL;
151
  if (msg == NULL) {
152
    DBGLOG(KERN_ERR "ERROR\t[%s()]: msg is a null pointer", __func__);
153
    goto end;
154
  }
155
  mutex_lock(&(g_tty_driver_mutex));
156
  if (g_tty_driver != NULL) {
157
    //smp_rmb();
158
    status = atomic_read(&(g_tty_driver->status));
159
  }
160
  else {
161
    status = RDP_STATUS_EXIT;
162
  }
163
  if (g_tty_driver == NULL || status != RDP_STATUS_NORMAL) {
164
  }
165
  else if (msg != NULL) {
166
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
167
    while (msg->len) {
168
      rdp_reg_num id;
169
      struct rdp_cmd * cmd = (struct rdp_cmd *)NULL;
170
      memcpy(&id, m->id.id, sizeof(rdp_reg_num));
171
      mtype |= m->type;
172
      mlen = m->len;
173
      if (msg->ack > 0 && mtype < 0x81) {
174
	spin_lock_irqsave(&rdp_cmd_lock, flags);
175
	for (i = 0; i < 16; i++) {
176
	  cmd = g_pend[i];
177
	  if (cmd != NULL) {
178
	    DBGLOG(KERN_INFO "INFO\t[%s()]: cmd->seqid = %d", __func__, cmd->seqid);
179
	    //smp_rmb();
180
	    lcompleted = atomic_read(&(cmd->completed));
181
	    if (cmd->seqid == msg->seq && lcompleted < 1) {
182
	      smp_mb__before_atomic_inc();
183
	      atomic_inc(&(cmd->completed));
184
	      found = 1;
185
	      g_pend[i] = NULL;
186
	      break;
187
	    }
188
	  }
189
	}
190
	spin_unlock_irqrestore(&rdp_cmd_lock, flags);
191
	if (likely(found > 0 && cmd != NULL)) {
192
	  completed_cmd_list_t * cmd_item = (completed_cmd_list_t *)NULL;
193
	  DBGLOG(KERN_INFO "INFO\t[%s()]: cmd found, queueing callback...", __func__);
194
	  if (cmd != NULL && cmd->aux != NULL) {
195
	    cmd_item = (completed_cmd_list_t *)(cmd->aux);
196
	    cmd->aux = (void *)NULL;
197
	  }
198
	  else {
199
	    cmd_item = (completed_cmd_list_t *)kzalloc(sizeof(completed_cmd_list_t), GFP_KERNEL);
200
	  }
201
	  cmd_item->cmd = cmd;
202
	  if (cmd != NULL && cmd->odata != NULL && cmd->olen > 0 && m->data != NULL && mlen > 0 && cmd->odata != m->data && cmd->olen == mlen) {
203
	    memcpy(cmd->odata, m->data, MINVAL(cmd->olen, mlen));
204
	    DBGLOG(KERN_INFO "INFO\t[%s()]: cmd->odata = %p; cmd->olen = %d; m->data = %p; m->len = %d", __func__, cmd->odata, cmd->olen, m->data, m->len);
205
	  }
206
	  compl_enq(cmd_item);
207
	  queue_work(g_complq, &g_complw);
208
	}
209
	else {
210
	  //DBGLOG(KERN_INFO "INFO\t[%s()]: cmd not found! (%d)", __func__, msg->seq);
211
	}
212
      }
213
      else if (mtype > 0 && m != NULL) {
214
	/* if an unsolicited cn packet is received, then it should be handled as a
215
	 * "virtual interrupt" received from the userspace daemon; so, queue up an
216
	 * ersatz irq handler:
217
	 */
218
	struct rdp_irq_data * irq_data = (struct rdp_irq_data *)(m->data);
219
	struct rdp_irq_entry * irq_entry = (struct rdp_irq_entry *)NULL;
220
	DBGLOG(KERN_INFO "INFO\t[%s()]: (IRQ)", __func__);
221
	mtype &= ~RDP_ASYNC;
222
	switch (mtype) {
223
	  case RDP_ADDPORT:
224
	    {
225
	      int i = 0;
226
	      DBGLOG(KERN_INFO "INFO\t[%s()]: calling tty_register_device()", __func__);
227
	      if (p_tty_mutex != NULL) {
228
		mutex_lock(p_tty_mutex);
229
	      }
230
	      i = g_port_count;
231
	      if (!(gdev = tty_register_device((struct tty_driver *)(g_tty_driver->driver), i, NULL))) {
232
		DBGLOG(KERN_ERR "ERROR\t[%s()]: tty_register_device() failed", __func__);
233
	      }
234
	      else if (g_ports[i].initialized > 0) {
235
		DBGLOG(KERN_ERR "ERROR\t[%s()]: port is already initialized", __func__);
236
	      }
237
	      else {
238
		DBGLOG(KERN_INFO "INFO\t[%s()]: tty_register_device() was successful", __func__);
239
		memset(&(g_ports[i]), 0, sizeof(struct rdp_port));
240
		mutex_init(&(g_ports[i].mut));
241
		mutex_lock(&(g_ports[i].mut));
242
		g_ports[i].initialized = 1;
243
		g_ports[i].g_ports_index = i;
244
		spin_lock_init(&(g_ports[i].cmd_lock));
245
		spin_lock_init(&(g_ports[i].status_lock));
246
		//smp_wmb();
247
		atomic_set(&(g_ports[i].open_count), 0);
248
		g_ports[i].rec.port = &(g_ports[i]);
249
		g_ports[i].rec.tty = g_ports[i].item;
250
		g_ports[i].rec.initialized = 1;
251
		g_ports[i].rec.owner = THIS_MODULE;
252
		if (g_tty_driver != NULL && g_tty_driver->driver != NULL && g_tty_driver->driver->name != NULL) {
253
		  scnprintf(g_ports[i].rec.name, RDP_MAXNAMELEN, "%s%d", g_tty_driver->driver->name, i);
254
		}
255
		spin_lock_init(&(g_ports[i].rec.lock));
256
		mutex_unlock(&(g_ports[i].mut));
257
		g_port_count++;
258
	      }
259
	      if (p_tty_mutex != NULL) {
260
		mutex_unlock(p_tty_mutex);
261
	      }
262
	    }
263
	    break;
264
	  case RDP_RXFULL:
265
	    {
266
		int idx = 0;
267
		int found = 0;
268
		const int nr = MAX_PORT;
269
		if (p_tty_mutex != NULL) {
270
		  mutex_lock(p_tty_mutex);
271
		}
272
		for (idx = 0; idx < nr; idx++) {
273
		  if (g_ports[idx].device_id == irq_data->device_id) {
274
		    found = 1;
275
		    break;
276
		  }
277
		}
278
		irq_entry = (struct rdp_irq_entry *)kzalloc(sizeof(struct rdp_irq_entry), GFP_KERNEL);
279
		if (irq_entry != NULL) {
280
		  irq_entry->data = irq_data;
281
		  if (found > 0) {
282
		    irq_entry->port = &(g_ports[idx]);
283
		  }
284
		  else {
285
		    irq_entry->port = &(g_ports[0]);
286
		  }
287
		  read_enq(irq_entry);
288
		  queue_work(g_readq, &g_readw);
289
		}
290
		if (p_tty_mutex != NULL) {
291
		  mutex_unlock(p_tty_mutex);
292
		}
293
	    }
294
	    break;
295
	  default:
296
	    {
297
	      DBGLOG(KERN_WARNING "WARNING\t[%s()]: INTERRUPT --> unrecognized opcode (\"0x%02x\")", __func__, mtype);
298
	    }
299
	    break;
300
	}
301
      }
302
      msg->len -= (sizeof(rdp_netlink_msg) + m->len);
303
      m = (rdp_netlink_msg *)(((u8 *)m) + m->len);
304
    }
305
  }
306
  mutex_unlock(&(g_tty_driver_mutex));
307
308
 end:;
309
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
310
}
311
312
313
static int rdp_netlink_send(struct rdp_record * dev, rdp_netlink_msg * msg, int seq, int memmode) {
314
	unsigned long flags;
315
	int rv = 0;
316
	char buf[512];
317
	struct cn_msg * m = (struct cn_msg *)buf;
318
	rdp_netlink_msg * w = (rdp_netlink_msg *)(m+1);
319
	DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
320
	if (dev == NULL) {
321
	  DBGLOG(KERN_WARNING "WARNING\t[%s()]: dev is a null pointer", __func__);
322
	  rv = -EINVAL;
323
	  goto end;
324
	}
325
	if (msg == NULL) {
326
	  DBGLOG(KERN_WARNING "WARNING\t[%s()]: msg is a null pointer", __func__);
327
	  rv = -EINVAL;
328
	  goto end;
329
	}
330
	memset(buf, 0, sizeof(buf));
331
	m->id.idx = CN_IDX_RDP;
332
	m->id.val = CN_VAL_RDP;
333
	spin_lock_irqsave(&(dev->lock), flags);
334
	m->seq = seq;
335
	spin_unlock_irqrestore(&(dev->lock), flags);
336
	rv = m->seq;
337
	m->len = sizeof(rdp_netlink_msg) + msg->len;
338
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call memcpy()...", __func__);
339
	memcpy(w, msg, m->len);
340
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cn_netlink_send()... {m->len = \"%d\"}", __func__, m->len);
341
	cn_netlink_send(m, 0, memmode);
342
  end:
343
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\").", __func__, rv);
344
	return rv;
345
}
346
347
static int rdp_init_netlink(void) {
348
	int rv = 0;
349
	struct cb_id rdp_id = {
350
		.idx		= CN_IDX_RDP,
351
		.val		= CN_VAL_RDP,
352
	};
353
	spin_lock_init(&(rdp_default_family.lock));
354
	DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
355
	rv = cn_add_callback(&rdp_id, "rdp", &rdp_cn_callback);
356
	DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
357
	return rv;
358
}
359
360
static void rdp_stop_netlink(void) {
361
	struct cb_id rdp_id = {
362
		.idx		= CN_IDX_RDP,
363
		.val		= CN_VAL_RDP,
364
	};
365
	DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
366
	cn_del_callback(&rdp_id);
367
	DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
368
}
369
370
int rdp_register_family(struct rdp_family * newf) {
371
	unsigned long flags;
372
	struct list_head * ent = (struct list_head *)NULL;
373
	struct list_head * n = (struct list_head *)NULL;
374
	struct rdp_family * f = (struct rdp_family *)NULL;
375
	int ret = 0;
376
377
	spin_lock_irqsave(&rdp_flock, flags);
378
	list_for_each_safe(ent, n, &rdp_families) {
379
	  f = list_entry(ent, struct rdp_family, family_entry);
380
	  if (f->fid == newf->fid) {
381
	    ret = -EEXIST;
382
	    break;
383
	  }
384
	}
385
386
	if (!ret) {
387
	  //smp_wmb();
388
	  atomic_set(&newf->refcnt, 0);
389
	  newf->need_exit = 0;
390
	  list_add_tail(&newf->family_entry, &rdp_families);
391
	}
392
	spin_unlock_irqrestore(&rdp_flock, flags);
393
394
	return ret;
395
}
396
397
void rdp_unregister_family(struct rdp_family * fent) {
398
	unsigned long flags;
399
	struct list_head * ent = (struct list_head *)NULL;
400
	struct list_head * n = (struct list_head *)NULL;
401
	struct rdp_family * f  = (struct rdp_family *)NULL;
402
	int refcnt = 0;
403
404
	spin_lock_irqsave(&rdp_flock, flags);
405
	list_for_each_safe(ent, n, &rdp_families) {
406
		f = list_entry(ent, struct rdp_family, family_entry);
407
		if (f->fid == fent->fid) {
408
			list_del(&fent->family_entry);
409
			break;
410
		}
411
	}
412
413
	fent->need_exit = 1;
414
415
	spin_unlock_irqrestore(&rdp_flock, flags);
416
417
	//smp_rmb();
418
	refcnt = atomic_read(&(fent->refcnt));
419
	while (refcnt) {
420
	  printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n", fent->fid, atomic_read(&fent->refcnt));
421
	  if (msleep_interruptible(1000)) {
422
	    flush_signals(current);
423
	  }
424
	  //smp_rmb();
425
	  refcnt = atomic_read(&(fent->refcnt));
426
	}
427
}
428
429
/*
430
 * Should be called under rdp_flock held.
431
 */
432
struct rdp_family * rdp_family_registered(u8 fid) {
433
	struct list_head * ent = (struct list_head *)NULL;
434
	struct list_head * n = (struct list_head *)NULL;
435
	struct rdp_family * f = (struct rdp_family *)NULL;
436
	int ret = 0;
437
	list_for_each_safe(ent, n, &rdp_families) {
438
		f = list_entry(ent, struct rdp_family, family_entry);
439
		if (f->fid == fid) {
440
			ret = 1;
441
			break;
442
		}
443
	}
444
	return (ret) ? f : NULL;
445
}
446
447
static void __rdp_family_put(struct rdp_family * f) {
448
	int tmp = 0;
449
	smp_mb__before_atomic_dec();
450
	tmp = atomic_dec_and_test(&f->refcnt);
451
	if (tmp) {
452
	  f->need_exit = 1;
453
	}
454
}
455
456
void rdp_family_put(struct rdp_family * f) {
457
	spin_lock(&rdp_flock);
458
	__rdp_family_put(f);
459
	spin_unlock(&rdp_flock);
460
}
461
462
static void __rdp_family_get(struct rdp_family *f) {
463
	smp_mb__before_atomic_inc();
464
	atomic_inc(&(f->refcnt));
465
}
466
467
void rdp_family_get(struct rdp_family *f) {
468
	spin_lock(&rdp_flock);
469
	__rdp_family_get(f);
470
	spin_unlock(&rdp_flock);
471
}
472
473
/*****/
474
/*****/
475
476
static int cmd_output(struct rdp_cmd * rcmd, int memmode) {
477
	unsigned long flags;
478
	int rv = 0;
479
	struct rdp_record * rec = (struct rdp_record *)NULL;
480
	struct rdp_family * f = (struct rdp_family *)NULL;
481
	unsigned char * cbuf = (unsigned char *)NULL;
482
	void * data = (void *)NULL;
483
	int len = 0;
484
	rdp_netlink_msg msg;
485
	unsigned char cmd = 0x00;
486
	struct rdp_port * port = (struct rdp_port *)NULL;
487
	struct tty_struct * tty = (struct tty_struct *)NULL;
488
	int ilen = 0;
489
	int olen = 0;
490
	void * idata = (void *)NULL;
491
	void * odata = (void *)NULL;
492
	uint32_t cmd_idx = 0x00000000;
493
494
	if (rcmd == NULL) {
495
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: rcmd is a NULL pointer", __func__);
496
	  rv = -EINVAL;
497
	  goto end;
498
	}
499
	else {
500
	  port = rcmd->port;
501
	  cmd = rcmd->cmd;
502
	  tty = rcmd->tty;
503
	  ilen = rcmd->ilen;
504
	  olen = rcmd->olen;
505
	  idata = rcmd->idata;
506
	  odata = rcmd->odata;
507
	  len = ilen;
508
	  data = idata;
509
	  cmd_idx = rcmd->cmd_idx;
510
	}
511
	if (ilen > 0 && idata == NULL) {
512
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: idata is a NULL pointer", __func__);
513
	  rv = -EINVAL;
514
	  goto end;
515
	}
516
	if (olen > 0 && odata == NULL) {
517
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: odata is a NULL pointer", __func__);
518
	  rv = -ENOMEM;
519
	  goto end;
520
	}
521
	if (cmd == RDP_PING || cmd > RDP_XCHAR) {
522
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: opcode not implemented (\"%8.8x\")", __func__, cmd);
523
	  rv = -EINVAL;
524
	  goto end;
525
	}
526
527
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", %d)", __func__, RDPCMD(cmd), cmd);
528
529
	rec = &(rcmd->port->rec);
530
531
	memset(&msg, 0, sizeof(rdp_netlink_msg));
532
	//smp_wmb();
533
	atomic_set(&(rec->refcnt), 0);
534
	INIT_COMPLETION(rec->released);
535
536
	spin_lock_irqsave(&rdp_flock, flags);
537
	f = &rdp_default_family;
538
	__rdp_family_get(f);
539
	rec->family = f;
540
	spin_unlock_irqrestore(&rdp_flock, flags);
541
542
	msg.type = cmd;
543
544
	if (len > 0 && data != NULL) {
545
	  msg.len = len + sizeof(uint32_t);
546
	  cbuf = (unsigned char *)kzalloc((sizeof(rdp_netlink_msg) + len), memmode);
547
	  if (cbuf == NULL) {
548
	    rv = -ENOMEM;
549
	    goto end;
550
	  }
551
	  else {
552
	    rdp_netlink_msg * pm = (rdp_netlink_msg *)cbuf;
553
	    uint32_t * pn = (uint32_t *)(pm+1);
554
	    unsigned char * pd = (unsigned char *)(pn+1);
555
	    memcpy(pm, &msg, sizeof(rdp_netlink_msg));
556
	    memcpy(pn, &cmd_idx, sizeof(uint32_t));
557
	    memcpy(pd, data, len);
558
	  }
559
	}
560
	else {
561
	  cbuf = (unsigned char *)kzalloc((sizeof(rdp_netlink_msg) + sizeof(uint32_t)), memmode);
562
	  if (cbuf == NULL) {
563
	    rv = -ENOMEM;
564
	    goto end;
565
	  }
566
	  else {
567
	    rdp_netlink_msg * pm = (rdp_netlink_msg *)cbuf;
568
	    uint32_t * pn = (uint32_t *)(pm+1);
569
	    memcpy(pm, &msg, sizeof(rdp_netlink_msg));
570
	    memcpy(pn, &cmd_idx, sizeof(uint32_t));
571
	  }
572
	}
573
	INIT_LIST_HEAD(&(rcmd->list));
574
	rcmd->seqid = rec->seq++;
575
	p_enq(rcmd);
576
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call rdp_netlink_send()...", __func__);
577
	rv = rdp_netlink_send(rec, (void *)cbuf, rcmd->seqid, memmode);
578
	DBGLOG(KERN_INFO "INFO\t[%s()]: (\" returned)", __func__);
579
580
	if (cbuf != NULL) {
581
	  kfree(cbuf);
582
	}
583
584
  end:
585
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\")", __func__, rv);
586
	return rv;
587
}
588
589
590
static struct list_head * __compl_enq(completed_cmd_list_t * cmd_item) {
591
  struct list_head * rv = (struct list_head *)NULL;
592
  int found = 0;
593
  int i = 0;
594
595
  if (cmd_item != NULL) {
596
    for (i = 0; i < 16; i++) {
597
      if (g_compl[i] == NULL) {
598
	found = 1;
599
	break;
600
      }
601
    }
602
    if (found) {
603
      g_compl[i] = cmd_item;
604
    }
605
    else {
606
      rv = NULL;
607
    }
608
  }
609
610
  return rv;
611
}
612
613
static struct list_head * compl_enq(completed_cmd_list_t * cmd_item) {
614
    unsigned long flags;
615
    struct list_head * rv = (struct list_head *)NULL;
616
617
    spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
618
    if (likely(cmd_item != NULL)) {
619
      rv = __compl_enq(cmd_item);
620
    }
621
    spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
622
623
    return rv;
624
}
625
626
static completed_cmd_list_t * __compl_deq(completed_cmd_list_t ** rcmd) {
627
  completed_cmd_list_t * rv = (completed_cmd_list_t *)NULL;
628
  int i = 0;
629
630
  for (i = 0; i < 16; i++) {
631
    if (g_compl[i] != NULL) {
632
      rv = g_compl[i];
633
      g_compl[i] = (completed_cmd_list_t *)NULL;
634
      break;
635
    }
636
  }
637
638
  /*
639
  if (list_empty(&rdp_completed_cmds)) {
640
    rv = (completed_cmd_list_t *)NULL;
641
  }
642
  else {
643
    rv = list_entry(rdp_completed_cmds.next, completed_cmd_list_t, list);
644
  }
645
  if (rv != NULL) {
646
    list_del_init(&(rv->list));
647
  }
648
  */
649
650
  if (rcmd != NULL) {
651
    *rcmd = rv;
652
  }
653
654
  return rv;
655
}
656
657
static completed_cmd_list_t * compl_deq(completed_cmd_list_t ** rcmd) {
658
  unsigned long flags;
659
  completed_cmd_list_t * rv = (completed_cmd_list_t *)NULL;
660
661
  spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
662
  rv = __compl_deq(rcmd);
663
  spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
664
665
  return rv;
666
}
667
668
669
static struct list_head * cmd_enq(struct rdp_cmd * rcmd) {
670
  unsigned long flags;
671
  int i = 0;
672
  int found = 0;
673
  struct list_head * rv = &rdp_outbound_cmd_list;
674
675
  if (rcmd != NULL) {
676
    spin_lock_irqsave(&rdp_cmd_lock, flags);
677
    for (i = 0; i < 16; i++) {
678
      if (g_cmds[i] == NULL) {
679
	found = 1;
680
	break;
681
      }
682
    }
683
    if (found) {
684
      g_cmds[i] = rcmd;
685
    }
686
    else {
687
      rv = NULL;
688
    }
689
    spin_unlock_irqrestore(&rdp_cmd_lock, flags);
690
  }
691
692
  return rv;
693
}
694
695
static struct rdp_cmd * cmd_deq(struct rdp_cmd ** rcmd) {
696
  unsigned long flags;
697
  int i = 0;
698
  struct rdp_cmd * rv = (struct rdp_cmd *)NULL;
699
700
  spin_lock_irqsave(&rdp_cmd_lock, flags);
701
  for (i = 0; i < 16; i++) {
702
    if (g_cmds[i] != NULL) {
703
      rv = g_cmds[i];
704
      g_cmds[i] = (struct rdp_cmd *)NULL;
705
      break;
706
    }
707
  }
708
  spin_unlock_irqrestore(&rdp_cmd_lock, flags);
709
710
  if (rcmd != NULL) {
711
    *rcmd = rv;
712
  }
713
714
  return rv;
715
}
716
717
static void read_enq(struct rdp_irq_entry * irq_entry) {
718
  unsigned long flags;
719
  int found = 0;
720
  int i = 0;
721
722
  if (irq_entry != NULL) {
723
    spin_lock_irqsave(&rdp_read_lock, flags);
724
    for (i = 0; i < 16; i++) {
725
      if (g_read[i] == NULL) {
726
	found = 1;
727
	break;
728
      }
729
    }
730
    if (found) {
731
      g_read[i] = irq_entry;
732
    }
733
    else {
734
      //rv = NULL;
735
    }
736
    spin_unlock_irqrestore(&rdp_read_lock, flags);
737
  }
738
739
740
  /*
741
  if (irq_entry != NULL) {
742
    INIT_LIST_HEAD(&(irq_entry->list));
743
    spin_lock_irqsave(&rdp_read_lock, flags);
744
    list_add_tail(&(irq_entry->list), &rdp_read_list);
745
    spin_unlock_irqrestore(&rdp_read_lock, flags);
746
  }
747
  */
748
}
749
750
static struct rdp_irq_entry * read_deq(struct rdp_irq_entry ** itm) {
751
  unsigned long flags;
752
  struct rdp_irq_entry * rv = (struct rdp_irq_entry *)NULL;
753
  int i = 0;
754
755
  spin_lock_irqsave(&rdp_read_lock, flags);
756
  for (i = 0; i < 16; i++) {
757
    if (g_read[i] != NULL) {
758
      rv = g_read[i];
759
      g_read[i] = (struct rdp_irq_entry *)NULL;
760
      break;
761
    }
762
  }
763
  spin_unlock_irqrestore(&rdp_read_lock, flags);
764
765
  /*
766
  spin_lock_irqsave(&rdp_read_lock, flags);
767
  rv = list_entry(rdp_read_list.next, struct rdp_irq_entry, list);
768
  if (rv != NULL) {
769
    list_del_init(&(rv->list));
770
  }
771
  spin_unlock_irqrestore(&rdp_read_lock, flags);
772
  */
773
774
  if (itm != NULL) {
775
    *itm = rv;
776
  }
777
778
  return rv;
779
}
780
781
static void write_enq(struct rdp_write_entry * write_entry) {
782
  unsigned long flags;
783
  int found = 0;
784
  int i = 0;
785
786
  if (write_entry != NULL) {
787
    spin_lock_irqsave(&rdp_write_lock, flags);
788
    for (i = 0; i < 16; i++) {
789
      if (g_write[i] == NULL) {
790
	found = 1;
791
	break;
792
      }
793
    }
794
    if (found) {
795
      g_write[i] = write_entry;
796
    }
797
    else {
798
      //rv = NULL;
799
    }
800
    spin_unlock_irqrestore(&rdp_write_lock, flags);
801
  }
802
803
  /*
804
    if (write_entry != NULL) {
805
      INIT_LIST_HEAD(&(write_entry->list));
806
      spin_lock_irqsave(&rdp_write_lock, flags);
807
      list_add_tail(&(write_entry->list), &rdp_write_list);
808
      spin_unlock_irqrestore(&rdp_write_lock, flags);
809
    }
810
  */
811
}
812
813
static struct rdp_write_entry * write_deq(struct rdp_write_entry ** itm) {
814
  unsigned long flags;
815
  struct rdp_write_entry * rv = (struct rdp_write_entry *)NULL;
816
  int i = 0;
817
818
  spin_lock_irqsave(&rdp_write_lock, flags);
819
  for (i = 0; i < 16; i++) {
820
    if (g_write[i] != NULL) {
821
      rv = g_write[i];
822
      g_write[i] = (struct rdp_write_entry *)NULL;
823
      break;
824
    }
825
  }
826
  spin_unlock_irqrestore(&rdp_write_lock, flags);
827
828
  /*
829
  spin_lock_irqsave(&rdp_write_lock, flags);
830
  rv = list_entry(rdp_write_list.next, struct rdp_write_entry, list);
831
  if (rv != NULL) {
832
    list_del_init(&(rv->list));
833
  }
834
  spin_unlock_irqrestore(&rdp_write_lock, flags);
835
  */
836
837
  if (itm != NULL) {
838
    *itm = rv;
839
  }
840
841
  return rv;
842
}
843
844
static void __cb_enq(struct rdp_cb_entry * cb_entry) {
845
  int found = 0;
846
  int i = 0;
847
848
  if (cb_entry != NULL) {
849
    for (i = 0; i < 16; i++) {
850
      if (g_cb[i] == NULL) {
851
	found = 1;
852
	break;
853
      }
854
    }
855
    if (found) {
856
      g_cb[i] = cb_entry;
857
    }
858
    else {
859
      //rv = NULL;
860
    }
861
  }
862
863
  /*
864
    if (cb_entry != NULL) {
865
      INIT_LIST_HEAD(&(cb_entry->list));
866
      spin_lock_irqsave(&rdp_cb_lock, flags);
867
      list_add_tail(&(cb_entry->list), &rdp_cb_list);
868
      spin_unlock_irqrestore(&rdp_cb_lock, flags);
869
    }
870
  */
871
}
872
873
static void cb_enq(struct rdp_cb_entry * cb_entry) {
874
    unsigned long flags;
875
876
    spin_lock_irqsave(&rdp_cb_lock, flags);
877
    __cb_enq(cb_entry);
878
    spin_unlock_irqrestore(&rdp_cb_lock, flags);
879
}
880
881
882
static struct rdp_cb_entry * __cb_deq(struct rdp_cb_entry ** itm) {
883
  struct rdp_cb_entry * rv = (struct rdp_cb_entry *)NULL;
884
  int i = 0;
885
886
  for (i = 0; i < 16; i++) {
887
    if (g_cb[i] != NULL) {
888
      rv = g_cb[i];
889
      g_cb[i] = (struct rdp_cb_entry *)NULL;
890
      break;
891
    }
892
  }
893
894
  /*
895
  rv = list_entry(rdp_cb_list.next, struct rdp_cb_entry, list);
896
  if (rv != NULL) {
897
    list_del_init(&(rv->list));
898
  }
899
  */
900
901
  if (itm != NULL) {
902
    *itm = rv;
903
  }
904
905
  return rv;
906
}
907
908
static struct rdp_cb_entry * cb_deq(struct rdp_cb_entry ** itm) {
909
    unsigned long flags;
910
    struct rdp_cb_entry * rv = (struct rdp_cb_entry *)NULL;
911
912
    spin_lock_irqsave(&rdp_cb_lock, flags);
913
    __cb_deq(&rv);
914
    if (itm != NULL) {
915
      *itm = rv;
916
    }
917
    spin_unlock_irqrestore(&rdp_cb_lock, flags);
918
919
    return rv;
920
}
921
922
923
static struct list_head * p_enq(struct rdp_cmd * rcmd) {
924
  unsigned long flags;
925
  int i = 0;
926
  int found = 0;
927
  struct list_head * rv = &rdp_outbound_cmd_list;
928
929
  if (rcmd != NULL) {
930
931
    spin_lock_irqsave(&rdp_cmd_lock, flags);
932
933
    for (i = 0; i < 16; i++) {
934
      if (g_pend[i] == NULL) {
935
	found = 1;
936
	break;
937
      }
938
    }
939
940
    if (found) {
941
      g_pend[i] = rcmd;
942
    }
943
    else {
944
      rv = NULL;
945
    }
946
947
    spin_unlock_irqrestore(&rdp_cmd_lock, flags);
948
  }
949
950
  return rv;
951
}
952
953
#ifdef DO_PDEQ
954
955
static struct rdp_cmd * p_deq(struct rdp_cmd ** rcmd) {
956
  unsigned long flags;
957
  int i = 0;
958
  struct rdp_cmd * rv = (struct rdp_cmd *)NULL;
959
960
  spin_lock_irqsave(&rdp_cmd_lock, flags);
961
  for (i = 0; i < 16; i++) {
962
    if (g_pend[i] != NULL) {
963
      rv = g_pend[i];
964
      g_pend[i] = (struct rdp_cmd *)NULL;
965
      break;
966
    }
967
  }
968
  spin_unlock_irqrestore(&rdp_cmd_lock, flags);
969
970
  if (rcmd != NULL) {
971
    *rcmd = rv;
972
  }
973
974
  return rv;
975
}
976
977
#endif
978
979
980
static int cmd_process_list(struct list_head * cmdlist) {
981
  int rv = 0;
982
  struct rdp_cmd * cmd = (struct rdp_cmd *)NULL;
983
984
  might_sleep();
985
986
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
987
988
  if (g_tty_driver != NULL) {
989
    do {
990
      cmd_deq(&cmd);
991
      if (cmd != NULL) {
992
	DBGLOG(KERN_INFO "INFO\t[%s()]: outputting RDP command", __func__);
993
//	cmd_output(cmd, GFP_ATOMIC);
994
	cmd_output(cmd, GFP_KERNEL);
995
      }
996
    } while (cmd != NULL);
997
  }
998
999
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1000
1001
  return rv;
1002
}
1003
1004
static struct rdp_cmd * cmd_send(struct rdp_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen, int memmode) {
1005
	int seqid = 0;
1006
	int cmd_idx = 0;
1007
	struct rdp_cmd * lcmd = (struct rdp_cmd *)NULL;
1008
1009
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", ilen = \"%d\", olen = \"%d\")", __func__, RDPCMD(cmd), ilen, olen);
1010
1011
	if (port == NULL) {
1012
	  goto end;
1013
	}
1014
1015
	lcmd = (struct rdp_cmd *)kzalloc(sizeof(struct rdp_cmd), memmode);
1016
1017
	if (lcmd == NULL) {
1018
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: lcmd == NULL", __func__);
1019
	  goto end;
1020
	}
1021
1022
	spin_lock_init(&(lcmd->lock));
1023
	lcmd->cmd = cmd;
1024
	lcmd->port = port;
1025
	lcmd->idata = idata;
1026
	lcmd->ilen = ilen;
1027
	lcmd->odata = odata;
1028
	lcmd->olen = olen;
1029
	lcmd->cmd_idx = cmd_idx;
1030
	lcmd->aux = (void *)kzalloc(sizeof(completed_cmd_list_t), memmode);
1031
	//smp_wmb();
1032
	atomic_set(&(lcmd->completed), 0);
1033
1034
	if (olen > 0 && lcmd->odata == NULL) {
1035
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: lcmd->odata == NULL", __func__);
1036
	  goto end;
1037
	}
1038
1039
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cmd_enq()...", __func__);
1040
	cmd_enq(lcmd);
1041
	DBGLOG(KERN_INFO "INFO\t[%s()]: cmd_enq() returned", __func__);
1042
1043
  end:;
1044
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (lcmd = \"%p\", seqid = \"%d\").", __func__, lcmd, seqid);
1045
	return lcmd;
1046
}
1047
1048
1049
static int __cmd_exec(struct rdp_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen, int memmode) {
1050
	unsigned long flags;
1051
	int rv = 0;
1052
	int seqid = 0;
1053
	int lcompleted = 0x00000000;
1054
	int cnt = 0;
1055
	const unsigned int max_timeout = 2000;	/* in jiffies: 1 jiffy = 0.004 sec	*/
1056
	struct rdp_cmd * lcmd = (struct rdp_cmd *)NULL;
1057
	DECLARE_COMPLETION_ONSTACK(tdone);
1058
	struct completion * ldone = (struct completion *)NULL;
1059
	//struct work_struct * lwork = (struct work_struct *)NULL;
1060
	//DECLARE_WORK(g_cmdw, rdp_cmdw_handler);
1061
	struct work_struct twork;
1062
	struct work_struct * lwork = &twork;
1063
1064
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", ilen = \"%d\", olen = \"%d\")", __func__, RDPCMD(cmd), ilen, olen);
1065
1066
	if (port == NULL) {
1067
	  rv = -EINVAL;
1068
	  goto end;
1069
	}
1070
1071
//	ldone = (struct completion *)kzalloc(sizeof(struct completion), memmode);
1072
	ldone = &tdone;
1073
	if (ldone == NULL) {
1074
	  rv = -ENOMEM;
1075
	  goto end;
1076
	}
1077
	else {
1078
//	  init_completion(ldone);
1079
	}
1080
1081
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cmd_send()...", __func__);
1082
	lcmd = cmd_send(port, cmd, idata, ilen, odata, olen, memmode);
1083
	DBGLOG(KERN_INFO "INFO\t[%s()]: cmd_send() returned", __func__);
1084
	if (lcmd == NULL) {
1085
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: \"lcmd\" is a NULL pointer", __func__);
1086
	  goto end;
1087
	}
1088
	lcmd->done = ldone;
1089
	DBGLOG(KERN_INFO "INFO\t[%s()]: queue_delayed_work() returned", __func__);
1090
1091
//	lwork = (struct work_struct *)kzalloc(sizeof(struct work_struct), memmode);
1092
	if (lwork == NULL) {
1093
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: \"lwork\" is a NULL pointer", __func__);
1094
	  goto end;
1095
	}
1096
//	INIT_WORK(lwork, rdp_cmdw_handler);
1097
	INIT_WORK_ON_STACK(lwork, rdp_cmdw_handler);
1098
1099
	do {
1100
	  DBGLOG(KERN_INFO "INFO\t[%s()]: waiting for completion... (%d)", __func__, cnt);
1101
//	  queue_work(g_cmdq, &g_cmdw);
1102
	  queue_work(g_cmdq, lwork);
1103
	  wait_for_completion_interruptible_timeout(ldone, max_timeout);
1104
	  flush_workqueue(g_cmdq);
1105
//	  spin_lock_irqsave(&(lcmd->lock), flags);
1106
//	  INIT_COMPLETION(*ldone);
1107
	  INIT_COMPLETION(tdone);
1108
	  //smp_rmb();
1109
	  lcompleted = atomic_read(&(lcmd->completed));
1110
//	  spin_unlock_irqrestore(&(lcmd->lock), flags);
1111
	  cnt++;
1112
	} while (!(lcompleted) && cnt < 5);
1113
	if (!lcompleted) {
1114
	  int i = 0;
1115
	  spin_lock_irqsave(&rdp_cmd_lock, flags);
1116
	  for (i = 0; i < 16; i++) {
1117
	    if (g_cmds[i] == lcmd) {
1118
	      g_cmds[i] = (struct rdp_cmd *)NULL;
1119
	      kfree(lcmd);
1120
	      lcmd = (struct rdp_cmd *)NULL;
1121
	    }
1122
	  }
1123
	  spin_unlock_irqrestore(&rdp_cmd_lock, flags);
1124
	}
1125
	DBGLOG(KERN_INFO "INFO\t[%s()]: (\" completed)", __func__);
1126
	if (lwork != NULL) {
1127
	  //kfree(lwork);
1128
	}
1129
1130
	if (lcmd != NULL && lcmd->olen > 0 && lcmd->odata != NULL && olen > 0 && odata != NULL && odata != lcmd->odata) {
1131
	  memcpy(odata, lcmd->odata, MINVAL(lcmd->olen,olen));
1132
	}
1133
	if (lcmd != NULL) {
1134
	  memset(lcmd, 0, sizeof(struct rdp_cmd));
1135
	  kfree(lcmd);
1136
	}
1137
1138
  end:;
1139
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\", seqid = \"%d\").", __func__, rv, seqid);
1140
	return rv;
1141
}
1142
1143
static int cmd_exec(struct rdp_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen) {
1144
    might_sleep();
1145
    return __cmd_exec(port, cmd, idata, ilen, odata, olen, GFP_KERNEL);
1146
}
1147
1148
1149
#define DO_RECEIVE	1
1150
#ifdef DO_RECEIVE
1151
1152
static int rdp_receive(struct rdp_port * port, int stat, int buflen, char * buf) {
1153
	int rv = 1;
1154
	unsigned char ch = 0;
1155
	struct tty_struct * tty = port->item;
1156
1157
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (stat = \"%d\", buflen = \"%d\")", __func__, stat, buflen);
1158
1159
	if (port == NULL || tty == NULL) {
1160
	  rv = -EINVAL;
1161
	  goto end;
1162
	}
1163
1164
	if (buflen == 1 && buf != NULL) {
1165
	  ch = buf[0];
1166
	  tty_flip_buffer_push(tty);
1167
	  tty_insert_flip_char(tty, ch, 0);
1168
	  tty_flip_buffer_push(tty);
1169
	}
1170
	else if (buflen > 1 && buf != NULL) {
1171
	  tty_flip_buffer_push(tty);
1172
	  tty_insert_flip_string(tty, buf, buflen);
1173
	  tty_flip_buffer_push(tty);
1174
	}
1175
1176
1177
  end:
1178
	return rv;
1179
}
1180
1181
#endif
1182
1183
1184
static int supp_write(struct tty_struct * tty, const unsigned char * buffer, int count) {
1185
    unsigned long flags;
1186
    int rv = 0;
1187
    int cnt = 0;
1188
    int done = 0;
1189
    struct rdp_port * port = (struct rdp_port *)NULL;
1190
    struct work_struct * lwork = (struct work_struct *)NULL;
1191
    const unsigned int max_timeout = 2000;	/* in jiffies: 1 jiffy = 0.004 sec	*/
1192
1193
//    might_sleep();
1194
1195
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1196
1197
    if (tty != NULL && tty->index > -1 && tty->index < MAX_PORT) {
1198
      port = &(g_ports[tty->index]);
1199
    }
1200
    if (port == NULL) {
1201
      DBGLOG(KERN_ERR "ERROR\t[%s()]: tty->index out of range", __func__);
1202
      rv = -ENOMEM;
1203
      goto end;
1204
    }
1205
    else if (port->initialized < 1 || atomic_read(&(port->open_count)) < 1) {
1206
      DBGLOG(KERN_ERR "ERROR\t[%s()]: port is not open", __func__);
1207
      rv = -EACCES;
1208
      goto end;
1209
    }
1210
    else {
1211
      struct rdp_write_entry * write_entry = (struct rdp_write_entry *)NULL;
1212
1213
      if (p_write_mutex != NULL) {
1214
//	mutex_lock(p_write_mutex);
1215
      }
1216
1217
//      write_entry = (struct rdp_write_entry *)kzalloc(sizeof(struct rdp_write_entry), GFP_ATOMIC);
1218
      write_entry = (struct rdp_write_entry *)kzalloc(sizeof(struct rdp_write_entry), GFP_KERNEL);
1219
      spin_lock_init(&(write_entry->lock));
1220
//    spin_lock_irqsave(&(write_entry->lock), flags);
1221
      write_entry->port = port;
1222
      write_entry->len = count;
1223
      write_entry->data = (unsigned char *)buffer;
1224
      write_entry->rv = 0;
1225
      write_entry->completed = 0;
1226
      init_completion(&(write_entry->done));
1227
1228
      write_enq(write_entry);
1229
//    spin_unlock_irqrestore(&(write_entry->lock), flags);
1230
      //spin_lock_irqsave(&rdp_write_lock, flags);
1231
      //queue_work(g_writeq, &g_writew);
1232
      //spin_unlock_irqrestore(&rdp_write_lock, flags);
1233
	do {
1234
	  lwork = (struct work_struct *)kzalloc(sizeof(struct work_struct), GFP_KERNEL);
1235
	  INIT_WORK(lwork, rdp_writew_handler);
1236
	  DBGLOG(KERN_INFO "INFO\t[%s()]: waiting for completion... (%d)", __func__, cnt);
1237
	  queue_work(g_writeq, lwork);
1238
//	  wait_for_completion_interruptible_timeout(&(write_entry->done), max_timeout);
1239
//	  wait_for_completion_timeout(&(write_entry->done), max_timeout);
1240
//	  flush_workqueue(g_writeq);
1241
	  spin_lock_irqsave(&(write_entry->lock), flags);
1242
	  if (write_entry->completed > 0) {
1243
	    done = 1;
1244
	    kfree(lwork);
1245
	    lwork = (struct work_struct *)NULL;
1246
	  }
1247
	  else {
1248
	    done = 0;
1249
	    write_entry->canceled = 1;
1250
	  }
1251
//	  INIT_COMPLETION(write_entry->done);
1252
	  spin_unlock_irqrestore(&(write_entry->lock), flags);
1253
	  cnt++;
1254
	} while (!done && cnt < 3);
1255
1256
      if (p_write_mutex != NULL) {
1257
//	mutex_unlock(p_write_mutex);
1258
      }
1259
1260
      rv = count;
1261
    }
1262
1263
  end:;
1264
    return rv;
1265
}
1266
1267
static int supp_open(struct tty_struct * tty, struct file * file) {
1268
  int rv = 0;
1269
  uint32_t fd = 0;
1270
  int oc = 0;
1271
  struct rdp_port * port = (struct rdp_port *)NULL;
1272
1273
  might_sleep();
1274
1275
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1276
1277
  if (likely(tty != NULL && tty->index > -1 && tty->index < MAX_PORT)) {
1278
    port = &(g_ports[tty->index]);
1279
  }
1280
  if (unlikely(port == NULL)) {
1281
    DBGLOG(KERN_ERR "ERROR\t[%s()]: tty->index out of range", __func__);
1282
    rv = -ENOMEM;
1283
    goto end;
1284
  }
1285
  else {
1286
1287
    if (likely(port->initialized == 1 && port->item == NULL)) {
1288
      port->item = tty;
1289
      port->rec.tty = port->item;
1290
      port->rec.port = port;
1291
      port->fp = file;
1292
    }
1293
1294
    //smp_rmb();
1295
    oc = atomic_read(&(port->open_count));
1296
    cmd_exec(port, RDP_OPEN, NULL, 0, &fd, sizeof(fd));
1297
    DBGLOG(KERN_INFO "INFO\t[%s()]: fd = %d", __func__, fd);
1298
    rv = fd;
1299
    if (oc == 0) {
1300
      cmd_exec(port, RDP_START, NULL, 0, NULL, 0);
1301
    }
1302
    smp_mb__before_atomic_inc();
1303
    atomic_inc(&(port->open_count));
1304
1305
  }
1306
1307
  end:;
1308
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1309
  return rv;
1310
}
1311
1312
static void supp_close(struct tty_struct * tty, struct file * file) {
1313
    int oc = 0;
1314
    struct rdp_port * port = (struct rdp_port *)NULL;
1315
1316
    might_sleep();
1317
1318
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1319
1320
    if (likely(tty != NULL && tty->index > -1 && tty->index < MAX_PORT && g_ports[tty->index].initialized > 0)) {
1321
      port = &(g_ports[tty->index]);
1322
    }
1323
    if (unlikely(port == NULL || port->item == NULL || port->initialized < 1)) {
1324
      DBGLOG(KERN_ERR "ERROR\t[%s()]: port or port->item is NULL or not initialized", __func__);
1325
    }
1326
    else {
1327
      //smp_rmb();
1328
      oc = atomic_read(&(port->open_count));
1329
      if (oc == 1) {
1330
	cmd_exec(port, RDP_STOP, NULL, 0, NULL, 0);
1331
      }
1332
      cmd_exec(port, RDP_CLOSE, NULL, 0, NULL, 0);
1333
      smp_mb__before_atomic_dec();
1334
      atomic_dec(&(port->open_count));
1335
    }
1336
}
1337
1338
int __init rdp_ops_setup(struct tty_operations * ops) {
1339
    int rv = 0;
1340
1341
    if (ops == NULL) {
1342
      rv = -EINVAL;
1343
      goto exit;
1344
    }
1345
    ops->open = supp_open;
1346
    ops->close = supp_close;
1347
    ops->write = supp_write;
1348
1349
  exit:;
1350
    return rv;
1351
}
1352
1353
int __init rdp_init(struct tty_driver * drv, struct mutex * tty_mutex) {
1354
  int rv = 0;
1355
1356
  might_sleep();
1357
1358
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1359
1360
  //mutex_lock(&(g_tty_driver_mutex));
1361
1362
  if (p_tty_mutex == NULL) {
1363
    p_tty_mutex = tty_mutex;
1364
  }
1365
  p_write_mutex = &g_write_mutex;
1366
  memset(p_write_mutex, 0x00, sizeof(struct mutex));
1367
  //mutex_init(p_write_mutex);
1368
1369
  memset(g_ports, 0, sizeof(g_ports));
1370
  memset(g_cmds, 0, sizeof(g_cmds));
1371
  memset(g_pend, 0, sizeof(g_pend));
1372
  memset(g_read, 0, sizeof(g_read));
1373
  memset(g_write, 0, sizeof(g_write));
1374
  memset(g_compl, 0, sizeof(g_compl));
1375
  memset(g_cb, 0, sizeof(g_cb));
1376
1377
  g_tty_driver = (struct rdp_tty *)kzalloc(sizeof(struct rdp_tty), GFP_KERNEL);
1378
  //mutex_init(&(g_tty_driver_mutex));
1379
  //mutex_lock(&(g_tty_driver_mutex));
1380
  g_tty_driver->driver = drv;
1381
  if (p_cb_mutex == NULL) {
1382
    memset(&g_cb_mutex, 0x00, sizeof(struct mutex));
1383
    p_cb_mutex = &g_cb_mutex;
1384
  }
1385
  //mutex_init(p_cb_mutex);
1386
  //mutex_lock(p_cb_mutex);
1387
  //smp_wmb();
1388
  atomic_set(&(g_tty_driver->status), RDP_STATUS_LOADING);
1389
  g_cbq = create_singlethread_workqueue(CBQ_NAME);
1390
  g_cmdq = create_singlethread_workqueue(Q_NAME);
1391
  g_complq = create_singlethread_workqueue(COMPLQ_NAME);
1392
  g_readq = create_singlethread_workqueue(READQ_NAME);
1393
  g_writeq = create_singlethread_workqueue(WRITEQ_NAME);
1394
  //smp_wmb();
1395
  atomic_set(&(g_tty_driver->status), RDP_STATUS_NORMAL);
1396
  g_initialized = 1;
1397
  //mutex_unlock(p_cb_mutex);
1398
  rdp_init_netlink();
1399
  //mutex_unlock(&(g_tty_driver_mutex));
1400
1401
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1402
  return rv;
1403
}
1404
1405
void __exit rdp_exit(struct tty_driver * tty) {
1406
  struct rdp_tty * l_tty_driver = (struct rdp_tty *)NULL;
1407
  might_sleep();
1408
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1409
  //mutex_lock(&(g_tty_driver_mutex));
1410
  if (g_tty_driver != NULL && g_initialized > 0) {
1411
    l_tty_driver = g_tty_driver;
1412
    //smp_wmb();
1413
    atomic_set(&(g_tty_driver->status), RDP_STATUS_EXIT);
1414
  }
1415
  g_initialized = 0;
1416
  //mutex_unlock(&(g_tty_driver_mutex));
1417
  destroy_workqueue(g_cbq);
1418
  destroy_workqueue(g_writeq);
1419
  destroy_workqueue(g_readq);
1420
  destroy_workqueue(g_cmdq);
1421
  destroy_workqueue(g_complq);
1422
  //mutex_lock(&(g_tty_driver_mutex));
1423
  if (g_tty_driver != NULL) {
1424
    if (g_tty_driver->driver != NULL) {
1425
      int i = 0;
1426
      for (i = 0; i < MAX_PORT; i++) {
1427
	if (g_ports[i].initialized) {
1428
	  //mutex_lock(&(g_ports[i].mut));
1429
	  tty_unregister_device(g_tty_driver->driver, i);
1430
	  g_ports[i].initialized = 0;
1431
	  //mutex_unlock(&(g_ports[i].mut));
1432
	}
1433
      }
1434
    }
1435
    g_tty_driver->driver = (struct tty_driver *)NULL;
1436
    g_tty_driver = (struct rdp_tty *)NULL;
1437
    //mutex_unlock(&(l_tty_driver->mut));
1438
    memset(g_tty_driver, 0, sizeof(struct rdp_tty));
1439
    kfree(l_tty_driver);
1440
    l_tty_driver = (struct rdp_tty *)NULL;
1441
  }
1442
  rdp_stop_netlink();
1443
  p_cb_mutex = (struct mutex *)NULL;
1444
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1445
}
1446
1447
static void rdp_cmdw_handler(struct work_struct * work) {
1448
  unsigned long status = RDP_STATUS_ERROR;
1449
  //mutex_lock(&(g_tty_driver_mutex));
1450
  if (g_tty_driver != NULL) {
1451
    //smp_rmb();
1452
    status = atomic_read(&(g_tty_driver->status));
1453
    if (g_tty_driver != NULL && status == RDP_STATUS_NORMAL) {
1454
      cmd_process_list(&rdp_outbound_cmd_list);
1455
    }
1456
  }
1457
  //mutex_unlock(&(g_tty_driver_mutex));
1458
}
1459
1460
/*
1461
static void rdp_complw_handler_old(struct work_struct * work) {
1462
    unsigned long flags;
1463
    completed_cmd_list_t * cmd_item = (completed_cmd_list_t *)NULL;
1464
    int lcompleted = 0;
1465
    struct list_head * ent = (struct list_head *)NULL;
1466
    struct list_head * n = (struct list_head *)NULL;
1467
1468
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1469
1470
    spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
1471
    list_for_each_safe(ent, n, &rdp_completed_cmds) {
1472
      if (list_empty(&rdp_completed_cmds)) {
1473
        cmd_item = NULL;
1474
      }
1475
      else {
1476
        cmd_item = list_entry(ent, completed_cmd_list_t, list);
1477
      }
1478
      if (cmd_item != NULL && cmd_item->cmd != NULL) {
1479
        struct rdp_cmd * cmd = cmd_item->cmd;
1480
        //smp_rmb();
1481
        lcompleted = atomic_read(&(cmd->completed));
1482
        if (lcompleted == 1) {
1483
	  smp_mb__before_atomic_inc();
1484
	  atomic_inc(&(cmd->completed));
1485
	  DBGLOG(KERN_INFO "INFO\t[%s()]: completing a cmd...", __func__);
1486
//	  complete_all(cmd->done);
1487
	  complete(cmd->done);
1488
	  DBGLOG(KERN_INFO "INFO\t[%s()]: (completed)", __func__);
1489
        }
1490
        list_del_init(&(cmd_item->list));
1491
      }
1492
    }
1493
    spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
1494
1495
    DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1496
}
1497
*/
1498
1499
static void rdp_complw_handler(struct work_struct * work) {
1500
    unsigned long flags;
1501
    completed_cmd_list_t * cmd_item = (completed_cmd_list_t *)NULL;
1502
    int lcompleted = 0;
1503
    int i = 0;
1504
1505
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1506
1507
    spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
1508
    for (i = 0; i < 16; i++) {
1509
      cmd_item = g_compl[i];
1510
      if (cmd_item != NULL && cmd_item->cmd != NULL) {
1511
	struct rdp_cmd * cmd = (struct rdp_cmd *)NULL;
1512
	cmd = cmd_item->cmd;
1513
	//spin_lock(&(cmd->lock));
1514
	//smp_rmb();
1515
	lcompleted = atomic_read(&(cmd->completed));
1516
	if (lcompleted >= 1) {
1517
	  smp_mb__before_atomic_inc();
1518
	  atomic_inc(&(cmd->completed));
1519
	  if (cmd->done != NULL) {
1520
	    DBGLOG(KERN_INFO "INFO\t[%s()]: completing a cmd...", __func__);
1521
	    complete_all(cmd->done);
1522
	    DBGLOG(KERN_INFO "INFO\t[%s()]: (completed)", __func__);
1523
	  }
1524
	  g_compl[i] = (completed_cmd_list_t *)NULL;
1525
	}
1526
	//spin_unlock(&(cmd->lock));
1527
      }
1528
    }
1529
    spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
1530
1531
    DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1532
}
1533
1534
static void rdp_readw_handler(struct work_struct * work) {
1535
  struct rdp_irq_entry * irq_entry = (struct rdp_irq_entry *)NULL;
1536
  struct rdp_irq_data * irq_data = (struct rdp_irq_data *)NULL;
1537
  struct tty_struct * tty = (struct tty_struct *)NULL;
1538
  unsigned char mut_locked = 0;
1539
1540
  might_sleep();
1541
1542
  if (p_tty_mutex != NULL) {
1543
    //mutex_lock(p_tty_mutex);
1544
    mut_locked = 1;
1545
  }
1546
  //mutex_lock(&(g_tty_driver_mutex));
1547
  if (g_tty_driver != NULL && mut_locked > 0) {
1548
    if (g_tty_driver->driver != NULL) {
1549
      read_deq(&irq_entry);
1550
      if (irq_entry != NULL) {
1551
	irq_data = irq_entry->data;
1552
	if (irq_entry->port != NULL && irq_data != NULL && irq_data->rx_len > 0 && irq_data->rx_buf != NULL && irq_entry->port->item != NULL && irq_entry->port->item->driver_data != NULL) {
1553
	  struct rdptty_serial * rdp = (struct rdptty_serial *)NULL;
1554
	  tty = irq_entry->port->item;
1555
	  rdp = (struct rdptty_serial *)(tty->driver_data);
1556
	  if (rdp != NULL) {
1557
	    //mutex_lock(&(rdp->mut));
1558
	    rdp_receive(irq_entry->port, 0, irq_data->rx_len, irq_data->rx_buf);
1559
	    //mutex_unlock(&(rdp->mut));
1560
	  }
1561
	}
1562
      }
1563
    }
1564
  }
1565
  mutex_unlock(&(g_tty_driver_mutex));
1566
  if (p_tty_mutex != NULL && mut_locked > 0) {
1567
    mutex_unlock(p_tty_mutex);
1568
  }
1569
}
1570
1571
static void rdp_writew_handler(struct work_struct * work) {
1572
  unsigned long flags;
1573
  struct rdp_port * port = (struct rdp_port *)NULL;
1574
  struct rdp_write_entry * write_entry = (struct rdp_write_entry *)NULL;
1575
  unsigned char * buf = (unsigned char *)NULL;
1576
  int len = 0;
1577
  unsigned char mut_locked = 0;
1578
  int rv = 0;
1579
1580
  might_sleep();
1581
1582
  if (p_tty_mutex != NULL) {
1583
    mutex_lock(p_tty_mutex);
1584
    mut_locked = 1;
1585
  }
1586
  mutex_lock(&(g_tty_driver_mutex));
1587
  if (g_tty_driver != NULL && mut_locked > 0) {
1588
    if (g_tty_driver->driver != NULL) {
1589
      write_deq(&write_entry);
1590
      if (write_entry != NULL) {
1591
	spin_lock_irqsave(&(write_entry->lock), flags);
1592
      }
1593
      if (write_entry != NULL && write_entry->data != NULL && write_entry->len > 0 && write_entry->canceled != 1 && write_entry->completed < 1) {
1594
	port = write_entry->port;
1595
	len = write_entry->len;
1596
	buf = write_entry->data;
1597
	if (port != NULL && buf != NULL && len > 0) {
1598
	  DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cmd_exec(RDP_WRITE)...", __func__);
1599
	  spin_unlock_irqrestore(&(write_entry->lock), flags);
1600
	  cmd_exec(port, RDP_WRITE, buf, len, &rv, sizeof(int));
1601
	  spin_lock_irqsave(&(write_entry->lock), flags);
1602
	  DBGLOG(KERN_INFO "INFO\t[%s()]: rv = %d", __func__, rv);
1603
	}
1604
	write_entry->rv = rv;
1605
	write_entry->completed = 1;
1606
	complete_all(&(write_entry->done));
1607
      }
1608
      if (write_entry != NULL) {
1609
	spin_unlock_irqrestore(&(write_entry->lock), flags);
1610
      }
1611
    }
1612
  }
1613
  mutex_unlock(&(g_tty_driver_mutex));
1614
  if (p_tty_mutex != NULL && mut_locked > 0) {
1615
    mutex_unlock(p_tty_mutex);
1616
  }
1617
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/drivers/serial/Kconfig (+1510 lines)
Line 0    Link Here 
1
#
2
# Serial device configuration
3
#
4
5
menu "Serial drivers"
6
	depends on HAS_IOMEM
7
8
config SERIAL_RDPUART
9
	tristate "Virtual UART support for Remote Desktop Protocol device redirection"
10
	select SERIAL_CORE
11
	select CONNECTOR
12
	default m
13
	help
14
	  For enabling serial port redirection by xrdp. If in doubt,
15
	  it is safe to select "n".
16
17
config SERIAL_TINY
18
	tristate "Demo TTY device"
19
	select SERIAL_CORE
20
	default m
21
	help
22
	  Demonstration TTY device driver. If in doubt,
23
	  it is safe to select "n".
24
25
#
26
# The new 8250/16550 serial drivers
27
config SERIAL_8250
28
	tristate "8250/16550 and compatible serial support"
29
	select SERIAL_CORE
30
	---help---
31
	  This selects whether you want to include the driver for the standard
32
	  serial ports.  The standard answer is Y.  People who might say N
33
	  here are those that are setting up dedicated Ethernet WWW/FTP
34
	  servers, or users that have one of the various bus mice instead of a
35
	  serial mouse and don't intend to use their machine's standard serial
36
	  port for anything.  (Note that the Cyclades and Stallion multi
37
	  serial port drivers do not need this driver built in for them to
38
	  work.)
39
40
	  To compile this driver as a module, choose M here: the
41
	  module will be called 8250.
42
	  [WARNING: Do not compile this driver as a module if you are using
43
	  non-standard serial ports, since the configuration information will
44
	  be lost when the driver is unloaded.  This limitation may be lifted
45
	  in the future.]
46
47
	  BTW1: If you have a mouseman serial mouse which is not recognized by
48
	  the X window system, try running gpm first.
49
50
	  BTW2: If you intend to use a software modem (also called Winmodem)
51
	  under Linux, forget it.  These modems are crippled and require
52
	  proprietary drivers which are only available under Windows.
53
54
	  Most people will say Y or M here, so that they can use serial mice,
55
	  modems and similar devices connecting to the standard serial ports.
56
57
config SERIAL_8250_CONSOLE
58
	bool "Console on 8250/16550 and compatible serial port"
59
	depends on SERIAL_8250=y
60
	select SERIAL_CORE_CONSOLE
61
	---help---
62
	  If you say Y here, it will be possible to use a serial port as the
63
	  system console (the system console is the device which receives all
64
	  kernel messages and warnings and which allows logins in single user
65
	  mode). This could be useful if some terminal or printer is connected
66
	  to that serial port.
67
68
	  Even if you say Y here, the currently visible virtual console
69
	  (/dev/tty0) will still be used as the system console by default, but
70
	  you can alter that using a kernel command line option such as
71
	  "console=ttyS1". (Try "man bootparam" or see the documentation of
72
	  your boot loader (grub or lilo or loadlin) about how to pass options
73
	  to the kernel at boot time.)
74
75
	  If you don't have a VGA card installed and you say Y here, the
76
	  kernel will automatically use the first serial line, /dev/ttyS0, as
77
	  system console.
78
79
	  You can set that using a kernel command line option such as
80
	  "console=uart8250,io,0x3f8,9600n8"
81
	  "console=uart8250,mmio,0xff5e0000,115200n8".
82
	  and it will switch to normal serial console when the corresponding 
83
	  port is ready.
84
	  "earlycon=uart8250,io,0x3f8,9600n8"
85
	  "earlycon=uart8250,mmio,0xff5e0000,115200n8".
86
	  it will not only setup early console.
87
88
	  If unsure, say N.
89
90
config FIX_EARLYCON_MEM
91
	bool
92
	depends on X86
93
	default y
94
95
config SERIAL_8250_GSC
96
	tristate
97
	depends on SERIAL_8250 && GSC
98
	default SERIAL_8250
99
100
config SERIAL_8250_PCI
101
	tristate "8250/16550 PCI device support" if EMBEDDED
102
	depends on SERIAL_8250 && PCI
103
	default SERIAL_8250
104
	help
105
	  This builds standard PCI serial support. You may be able to
106
	  disable this feature if you only need legacy serial support.
107
	  Saves about 9K.
108
109
config SERIAL_8250_PNP
110
	tristate "8250/16550 PNP device support" if EMBEDDED
111
	depends on SERIAL_8250 && PNP
112
	default SERIAL_8250
113
	help
114
	  This builds standard PNP serial support. You may be able to
115
	  disable this feature if you only need legacy serial support.
116
117
config SERIAL_8250_HP300
118
	tristate
119
	depends on SERIAL_8250 && HP300
120
	default SERIAL_8250
121
122
config SERIAL_8250_CS
123
	tristate "8250/16550 PCMCIA device support"
124
	depends on PCMCIA && SERIAL_8250
125
	---help---
126
	  Say Y here to enable support for 16-bit PCMCIA serial devices,
127
	  including serial port cards, modems, and the modem functions of
128
	  multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are
129
	  credit-card size devices often used with laptops.)
130
131
	  To compile this driver as a module, choose M here: the
132
	  module will be called serial_cs.
133
134
	  If unsure, say N.
135
136
config SERIAL_8250_NR_UARTS
137
	int "Maximum number of 8250/16550 serial ports"
138
	depends on SERIAL_8250
139
	default "4"
140
	help
141
	  Set this to the number of serial ports you want the driver
142
	  to support.  This includes any ports discovered via ACPI or
143
	  PCI enumeration and any ports that may be added at run-time
144
	  via hot-plug, or any ISA multi-port serial cards.
145
146
config SERIAL_8250_RUNTIME_UARTS
147
	int "Number of 8250/16550 serial ports to register at runtime"
148
	depends on SERIAL_8250
149
	range 0 SERIAL_8250_NR_UARTS
150
	default "4"
151
	help
152
	  Set this to the maximum number of serial ports you want
153
	  the kernel to register at boot time.  This can be overridden
154
	  with the module parameter "nr_uarts", or boot-time parameter
155
	  8250.nr_uarts
156
157
config SERIAL_8250_EXTENDED
158
	bool "Extended 8250/16550 serial driver options"
159
	depends on SERIAL_8250
160
	help
161
	  If you wish to use any non-standard features of the standard "dumb"
162
	  driver, say Y here. This includes HUB6 support, shared serial
163
	  interrupts, special multiport support, support for more than the
164
	  four COM 1/2/3/4 boards, etc.
165
166
	  Note that the answer to this question won't directly affect the
167
	  kernel: saying N will just cause the configurator to skip all
168
	  the questions about serial driver options. If unsure, say N.
169
170
config SERIAL_8250_MANY_PORTS
171
	bool "Support more than 4 legacy serial ports"
172
	depends on SERIAL_8250_EXTENDED && !IA64
173
	help
174
	  Say Y here if you have dumb serial boards other than the four
175
	  standard COM 1/2/3/4 ports. This may happen if you have an AST
176
	  FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
177
	  from <http://www.tldp.org/docs.html#howto>), or other custom
178
	  serial port hardware which acts similar to standard serial port
179
	  hardware. If you only use the standard COM 1/2/3/4 ports, you can
180
	  say N here to save some memory. You can also say Y if you have an
181
	  "intelligent" multiport card such as Cyclades, Digiboards, etc.
182
183
#
184
# Multi-port serial cards
185
#
186
187
config SERIAL_8250_FOURPORT
188
	tristate "Support Fourport cards"
189
	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
190
	help
191
	  Say Y here if you have an AST FourPort serial board.
192
193
	  To compile this driver as a module, choose M here: the module
194
	  will be called 8250_fourport.
195
196
config SERIAL_8250_ACCENT
197
	tristate "Support Accent cards"
198
	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
199
	help
200
	  Say Y here if you have an Accent Async serial board.
201
202
	  To compile this driver as a module, choose M here: the module
203
	  will be called 8250_accent.
204
205
config SERIAL_8250_BOCA
206
	tristate "Support Boca cards"
207
	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
208
	help
209
	  Say Y here if you have a Boca serial board.  Please read the Boca
210
	  mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
211
212
	  To compile this driver as a module, choose M here: the module
213
	  will be called 8250_boca.
214
215
config SERIAL_8250_EXAR_ST16C554
216
	tristate "Support Exar ST16C554/554D Quad UART"
217
	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
218
	help
219
	  The Uplogix Envoy TU301 uses this Exar Quad UART.  If you are
220
	  tinkering with your Envoy TU301, or have a machine with this UART,
221
	  say Y here.
222
223
	  To compile this driver as a module, choose M here: the module
224
	  will be called 8250_exar_st16c554.
225
226
config SERIAL_8250_HUB6
227
	tristate "Support Hub6 cards"
228
	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
229
	help
230
	  Say Y here if you have a HUB6 serial board.
231
232
	  To compile this driver as a module, choose M here: the module
233
	  will be called 8250_hub6.
234
235
config SERIAL_8250_SHARE_IRQ
236
	bool "Support for sharing serial interrupts"
237
	depends on SERIAL_8250_EXTENDED
238
	help
239
	  Some serial boards have hardware support which allows multiple dumb
240
	  serial ports on the same board to share a single IRQ. To enable
241
	  support for this in the serial driver, say Y here.
242
243
config SERIAL_8250_DETECT_IRQ
244
	bool "Autodetect IRQ on standard ports (unsafe)"
245
	depends on SERIAL_8250_EXTENDED
246
	help
247
	  Say Y here if you want the kernel to try to guess which IRQ
248
	  to use for your serial port.
249
250
	  This is considered unsafe; it is far better to configure the IRQ in
251
	  a boot script using the setserial command.
252
253
	  If unsure, say N.
254
255
config SERIAL_8250_RSA
256
	bool "Support RSA serial ports"
257
	depends on SERIAL_8250_EXTENDED
258
	help
259
	  ::: To be written :::
260
261
config SERIAL_8250_MCA
262
	tristate "Support 8250-type ports on MCA buses"
263
	depends on SERIAL_8250 != n && MCA
264
	help
265
	  Say Y here if you have a MCA serial ports.
266
267
	  To compile this driver as a module, choose M here: the module
268
	  will be called 8250_mca.
269
270
config SERIAL_8250_ACORN
271
	tristate "Acorn expansion card serial port support"
272
	depends on ARCH_ACORN && SERIAL_8250
273
	help
274
	  If you have an Atomwide Serial card or Serial Port card for an Acorn
275
	  system, say Y to this option.  The driver can handle 1, 2, or 3 port
276
	  cards.  If unsure, say N.
277
278
config SERIAL_8250_AU1X00
279
	bool "Au1x00 serial port support"
280
	depends on SERIAL_8250 != n && SOC_AU1X00
281
	help
282
	  If you have an Au1x00 SOC based board and want to use the serial port,
283
	  say Y to this option. The driver can handle up to 4 serial ports,
284
	  depending on the SOC. If unsure, say N.
285
286
config SERIAL_8250_RM9K
287
	bool "Support for MIPS RM9xxx integrated serial port"
288
	depends on SERIAL_8250 != n && SERIAL_RM9000
289
	select SERIAL_8250_SHARE_IRQ
290
	help
291
	  Selecting this option will add support for the integrated serial
292
	  port hardware found on MIPS RM9122 and similar processors.
293
	  If unsure, say N.
294
295
comment "Non-8250 serial port support"
296
297
config SERIAL_AMBA_PL010
298
	tristate "ARM AMBA PL010 serial port support"
299
	depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
300
	select SERIAL_CORE
301
	help
302
	  This selects the ARM(R) AMBA(R) PrimeCell PL010 UART.  If you have
303
	  an Integrator/AP or Integrator/PP2 platform, or if you have a
304
	  Cirrus Logic EP93xx CPU, say Y or M here.
305
306
	  If unsure, say N.
307
308
config SERIAL_AMBA_PL010_CONSOLE
309
	bool "Support for console on AMBA serial port"
310
	depends on SERIAL_AMBA_PL010=y
311
	select SERIAL_CORE_CONSOLE
312
	---help---
313
	  Say Y here if you wish to use an AMBA PrimeCell UART as the system
314
	  console (the system console is the device which receives all kernel
315
	  messages and warnings and which allows logins in single user mode).
316
317
	  Even if you say Y here, the currently visible framebuffer console
318
	  (/dev/tty0) will still be used as the system console by default, but
319
	  you can alter that using a kernel command line option such as
320
	  "console=ttyAM0". (Try "man bootparam" or see the documentation of
321
	  your boot loader (lilo or loadlin) about how to pass options to the
322
	  kernel at boot time.)
323
324
config SERIAL_AMBA_PL011
325
	tristate "ARM AMBA PL011 serial port support"
326
	depends on ARM_AMBA
327
	select SERIAL_CORE
328
	help
329
	  This selects the ARM(R) AMBA(R) PrimeCell PL011 UART.  If you have
330
	  an Integrator/PP2, Integrator/CP or Versatile platform, say Y or M
331
	  here.
332
333
	  If unsure, say N.
334
335
config SERIAL_AMBA_PL011_CONSOLE
336
	bool "Support for console on AMBA serial port"
337
	depends on SERIAL_AMBA_PL011=y
338
	select SERIAL_CORE_CONSOLE
339
	---help---
340
	  Say Y here if you wish to use an AMBA PrimeCell UART as the system
341
	  console (the system console is the device which receives all kernel
342
	  messages and warnings and which allows logins in single user mode).
343
344
	  Even if you say Y here, the currently visible framebuffer console
345
	  (/dev/tty0) will still be used as the system console by default, but
346
	  you can alter that using a kernel command line option such as
347
	  "console=ttyAMA0". (Try "man bootparam" or see the documentation of
348
	  your boot loader (lilo or loadlin) about how to pass options to the
349
	  kernel at boot time.)
350
351
config SERIAL_SB1250_DUART
352
	tristate "BCM1xxx on-chip DUART serial support"
353
	depends on SIBYTE_SB1xxx_SOC=y
354
	select SERIAL_CORE
355
	default y
356
	---help---
357
	  Support for the asynchronous serial interface (DUART) included in
358
	  the BCM1250 and derived System-On-a-Chip (SOC) devices.  Note that
359
	  the letter D in DUART stands for "dual", which is how the device
360
	  is implemented.  Depending on the SOC configuration there may be
361
	  one or more DUARTs available of which all are handled.
362
363
	  If unsure, say Y.  To compile this driver as a module, choose M here:
364
	  the module will be called sb1250-duart.
365
366
config SERIAL_SB1250_DUART_CONSOLE
367
	bool "Support for console on a BCM1xxx DUART serial port"
368
	depends on SERIAL_SB1250_DUART=y
369
	select SERIAL_CORE_CONSOLE
370
	default y
371
	---help---
372
	  If you say Y here, it will be possible to use a serial port as the
373
	  system console (the system console is the device which receives all
374
	  kernel messages and warnings and which allows logins in single user
375
	  mode).
376
377
	  If unsure, say Y.
378
379
config SERIAL_ATMEL
380
	bool "AT91 / AT32 on-chip serial port support"
381
	depends on (ARM && ARCH_AT91) || AVR32
382
	select SERIAL_CORE
383
	help
384
	  This enables the driver for the on-chip UARTs of the Atmel
385
	  AT91 and AT32 processors.
386
387
config SERIAL_ATMEL_CONSOLE
388
	bool "Support for console on AT91 / AT32 serial port"
389
	depends on SERIAL_ATMEL=y
390
	select SERIAL_CORE_CONSOLE
391
	help
392
	  Say Y here if you wish to use an on-chip UART on a Atmel
393
	  AT91 or AT32 processor as the system console (the system
394
	  console is the device which receives all kernel messages and
395
	  warnings and which allows logins in single user mode).
396
397
config SERIAL_ATMEL_PDC
398
	bool "Support DMA transfers on AT91 / AT32 serial port"
399
	depends on SERIAL_ATMEL
400
	default y
401
	help
402
	  Say Y here if you wish to use the PDC to do DMA transfers to
403
	  and from the Atmel AT91 / AT32 serial port. In order to
404
	  actually use DMA transfers, make sure that the use_dma_tx
405
	  and use_dma_rx members in the atmel_uart_data struct is set
406
	  appropriately for each port.
407
408
	  Note that break and error handling currently doesn't work
409
	  properly when DMA is enabled. Make sure that ports where
410
	  this matters don't use DMA.
411
412
config SERIAL_ATMEL_TTYAT
413
	bool "Install as device ttyATn instead of ttySn"
414
	depends on SERIAL_ATMEL=y
415
	help
416
	  Say Y here if you wish to have the internal AT91 / AT32 UARTs
417
	  appear as /dev/ttyATn (major 204, minor starting at 154)
418
	  instead of the normal /dev/ttySn (major 4, minor starting at
419
	  64). This is necessary if you also want other UARTs, such as
420
	  external 8250/16C550 compatible UARTs.
421
	  The ttySn nodes are legally reserved for the 8250 serial driver
422
	  but are often misused by other serial drivers.
423
424
	  To use this, you should create suitable ttyATn device nodes in
425
	  /dev/, and pass "console=ttyATn" to the kernel.
426
427
	  Say Y if you have an external 8250/16C550 UART.  If unsure, say N.
428
429
config SERIAL_KS8695
430
	bool "Micrel KS8695 (Centaur) serial port support"
431
	depends on ARCH_KS8695
432
	select SERIAL_CORE
433
	help
434
	  This selects the Micrel Centaur KS8695 UART.  Say Y here.
435
436
config SERIAL_KS8695_CONSOLE
437
	bool "Support for console on KS8695 (Centaur) serial port"
438
	depends on SERIAL_KS8695=y
439
	select SERIAL_CORE_CONSOLE
440
	help
441
	  Say Y here if you wish to use a KS8695 (Centaur) UART as the
442
	  system console (the system console is the device which
443
	  receives all kernel messages and warnings and which allows
444
	  logins in single user mode).
445
446
config SERIAL_CLPS711X
447
	tristate "CLPS711X serial port support"
448
	depends on ARM && ARCH_CLPS711X
449
	select SERIAL_CORE
450
	help
451
	  ::: To be written :::
452
453
config SERIAL_CLPS711X_CONSOLE
454
	bool "Support for console on CLPS711X serial port"
455
	depends on SERIAL_CLPS711X=y
456
	select SERIAL_CORE_CONSOLE
457
	help
458
	  Even if you say Y here, the currently visible virtual console
459
	  (/dev/tty0) will still be used as the system console by default, but
460
	  you can alter that using a kernel command line option such as
461
	  "console=ttyCL1". (Try "man bootparam" or see the documentation of
462
	  your boot loader (lilo or loadlin) about how to pass options to the
463
	  kernel at boot time.)
464
465
config SERIAL_SAMSUNG
466
	tristate "Samsung SoC serial support"
467
	depends on ARM && PLAT_S3C
468
	select SERIAL_CORE
469
	help
470
	  Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
471
	  providing /dev/ttySAC0, 1 and 2 (note, some machines may not
472
	  provide all of these ports, depending on how the serial port
473
	  pins are configured.
474
475
config SERIAL_SAMSUNG_UARTS
476
	int
477
	depends on ARM && PLAT_S3C
478
	default 2 if ARCH_S3C2400
479
	default 4 if ARCH_S5PC1XX || ARCH_S3C64XX || CPU_S3C2443
480
	default 3
481
	help
482
	  Select the number of available UART ports for the Samsung S3C
483
	  serial driver
484
	
485
config SERIAL_SAMSUNG_DEBUG
486
	bool "Samsung SoC serial debug"
487
	depends on SERIAL_SAMSUNG && DEBUG_LL
488
	help
489
	  Add support for debugging the serial driver. Since this is
490
	  generally being used as a console, we use our own output
491
	  routines that go via the low-level debug printascii()
492
	  function.
493
494
config SERIAL_SAMSUNG_CONSOLE
495
	bool "Support for console on Samsung SoC serial port"
496
	depends on SERIAL_SAMSUNG=y
497
	select SERIAL_CORE_CONSOLE
498
	help
499
	  Allow selection of the S3C24XX on-board serial ports for use as
500
	  an virtual console.
501
502
	  Even if you say Y here, the currently visible virtual console
503
	  (/dev/tty0) will still be used as the system console by default, but
504
	  you can alter that using a kernel command line option such as
505
	  "console=ttySACx". (Try "man bootparam" or see the documentation of
506
	  your boot loader about how to pass options to the kernel at
507
	  boot time.)
508
509
config SERIAL_S3C2400
510
	tristate "Samsung S3C2410 Serial port support"
511
	depends on ARM && SERIAL_SAMSUNG && CPU_S3C2400
512
	default y if CPU_S3C2400
513
	help
514
	  Serial port support for the Samsung S3C2400 SoC
515
516
config SERIAL_S3C2410
517
	tristate "Samsung S3C2410 Serial port support"
518
	depends on SERIAL_SAMSUNG && CPU_S3C2410
519
	default y if CPU_S3C2410
520
	help
521
	  Serial port support for the Samsung S3C2410 SoC
522
523
config SERIAL_S3C2412
524
	tristate "Samsung S3C2412/S3C2413 Serial port support"
525
	depends on SERIAL_SAMSUNG && CPU_S3C2412
526
	default y if CPU_S3C2412
527
	help
528
	  Serial port support for the Samsung S3C2412 and S3C2413 SoC
529
530
config SERIAL_S3C2440
531
	tristate "Samsung S3C2440/S3C2442 Serial port support"
532
	depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442)
533
	default y if CPU_S3C2440
534
	default y if CPU_S3C2442
535
	help
536
	  Serial port support for the Samsung S3C2440 and S3C2442 SoC
537
538
config SERIAL_S3C24A0
539
	tristate "Samsung S3C24A0 Serial port support"
540
	depends on SERIAL_SAMSUNG && CPU_S3C24A0
541
	default y if CPU_S3C24A0
542
	help
543
	  Serial port support for the Samsung S3C24A0 SoC
544
545
config SERIAL_S3C6400
546
	tristate "Samsung S3C6400/S3C6410 Serial port support"
547
	depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410)
548
	default y
549
	help
550
	  Serial port support for the Samsung S3C6400 and S3C6410
551
	  SoCs
552
553
config SERIAL_S5PC100
554
	tristate "Samsung S5PC100 Serial port support"
555
	depends on SERIAL_SAMSUNG && CPU_S5PC100
556
	default y
557
	help
558
	  Serial port support for the Samsung S5PC100 SoCs
559
560
config SERIAL_MAX3100
561
	tristate "MAX3100 support"
562
	depends on SPI
563
	select SERIAL_CORE
564
	help
565
	  MAX3100 chip support
566
567
config SERIAL_DZ
568
	bool "DECstation DZ serial driver"
569
	depends on MACH_DECSTATION && 32BIT
570
	select SERIAL_CORE
571
	default y
572
	---help---
573
	  DZ11-family serial controllers for DECstations and VAXstations,
574
	  including the DC7085, M7814, and M7819.
575
576
config SERIAL_DZ_CONSOLE
577
	bool "Support console on DECstation DZ serial driver"
578
	depends on SERIAL_DZ=y
579
	select SERIAL_CORE_CONSOLE
580
	default y
581
	---help---
582
	  If you say Y here, it will be possible to use a serial port as the
583
	  system console (the system console is the device which receives all
584
	  kernel messages and warnings and which allows logins in single user
585
	  mode).
586
587
	  Note that the firmware uses ttyS3 as the serial console on
588
	  DECstations that use this driver.
589
590
	  If unsure, say Y.
591
592
config SERIAL_ZS
593
	tristate "DECstation Z85C30 serial support"
594
	depends on MACH_DECSTATION
595
	select SERIAL_CORE
596
	default y
597
	---help---
598
	  Support for the Zilog 85C350 serial communications controller used
599
	  for serial ports in newer DECstation systems.  These include the
600
	  DECsystem 5900 and all models of the DECstation and DECsystem 5000
601
	  systems except from model 200.
602
603
	  If unsure, say Y.  To compile this driver as a module, choose M here:
604
	  the module will be called zs.
605
606
config SERIAL_ZS_CONSOLE
607
	bool "Support for console on a DECstation Z85C30 serial port"
608
	depends on SERIAL_ZS=y
609
	select SERIAL_CORE_CONSOLE
610
	default y
611
	---help---
612
	  If you say Y here, it will be possible to use a serial port as the
613
	  system console (the system console is the device which receives all
614
	  kernel messages and warnings and which allows logins in single user
615
	  mode).
616
617
	  Note that the firmware uses ttyS1 as the serial console on the
618
	  Maxine and ttyS3 on the others using this driver.
619
620
	  If unsure, say Y.
621
622
config SERIAL_21285
623
	tristate "DC21285 serial port support"
624
	depends on ARM && FOOTBRIDGE
625
	select SERIAL_CORE
626
	help
627
	  If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
628
	  PCI bridge you can enable its onboard serial port by enabling this
629
	  option.
630
631
config SERIAL_21285_CONSOLE
632
	bool "Console on DC21285 serial port"
633
	depends on SERIAL_21285=y
634
	select SERIAL_CORE_CONSOLE
635
	help
636
	  If you have enabled the serial port on the 21285 footbridge you can
637
	  make it the console by answering Y to this option.
638
639
	  Even if you say Y here, the currently visible virtual console
640
	  (/dev/tty0) will still be used as the system console by default, but
641
	  you can alter that using a kernel command line option such as
642
	  "console=ttyFB". (Try "man bootparam" or see the documentation of
643
	  your boot loader (lilo or loadlin) about how to pass options to the
644
	  kernel at boot time.)
645
646
config SERIAL_MPSC
647
	bool "Marvell MPSC serial port support"
648
	depends on PPC32 && MV64X60
649
	select SERIAL_CORE
650
	help
651
	  Say Y here if you want to use the Marvell MPSC serial controller.
652
653
config SERIAL_MPSC_CONSOLE
654
	bool "Support for console on Marvell MPSC serial port"
655
	depends on SERIAL_MPSC
656
	select SERIAL_CORE_CONSOLE
657
	help
658
	  Say Y here if you want to support a serial console on a Marvell MPSC.
659
660
config SERIAL_PXA
661
	bool "PXA serial port support"
662
	depends on ARCH_PXA || ARCH_MMP
663
	select SERIAL_CORE
664
	help
665
	  If you have a machine based on an Intel XScale PXA2xx CPU you
666
	  can enable its onboard serial ports by enabling this option.
667
668
config SERIAL_PXA_CONSOLE
669
	bool "Console on PXA serial port"
670
	depends on SERIAL_PXA
671
	select SERIAL_CORE_CONSOLE
672
	help
673
	  If you have enabled the serial port on the Intel XScale PXA
674
	  CPU you can make it the console by answering Y to this option.
675
676
	  Even if you say Y here, the currently visible virtual console
677
	  (/dev/tty0) will still be used as the system console by default, but
678
	  you can alter that using a kernel command line option such as
679
	  "console=ttySA0". (Try "man bootparam" or see the documentation of
680
	  your boot loader (lilo or loadlin) about how to pass options to the
681
	  kernel at boot time.)
682
683
config SERIAL_SA1100
684
	bool "SA1100 serial port support"
685
	depends on ARM && ARCH_SA1100
686
	select SERIAL_CORE
687
	help
688
	  If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
689
	  can enable its onboard serial port by enabling this option.
690
	  Please read <file:Documentation/arm/SA1100/serial_UART> for further
691
	  info.
692
693
config SERIAL_SA1100_CONSOLE
694
	bool "Console on SA1100 serial port"
695
	depends on SERIAL_SA1100
696
	select SERIAL_CORE_CONSOLE
697
	help
698
	  If you have enabled the serial port on the SA1100/SA1110 StrongARM
699
	  CPU you can make it the console by answering Y to this option.
700
701
	  Even if you say Y here, the currently visible virtual console
702
	  (/dev/tty0) will still be used as the system console by default, but
703
	  you can alter that using a kernel command line option such as
704
	  "console=ttySA0". (Try "man bootparam" or see the documentation of
705
	  your boot loader (lilo or loadlin) about how to pass options to the
706
	  kernel at boot time.)
707
708
config SERIAL_BFIN
709
	tristate "Blackfin serial port support"
710
	depends on BLACKFIN
711
	select SERIAL_CORE
712
	select SERIAL_BFIN_UART0 if (BF531 || BF532 || BF533 || BF561)
713
	help
714
	  Add support for the built-in UARTs on the Blackfin.
715
716
	  To compile this driver as a module, choose M here: the
717
	  module will be called bfin_5xx.
718
719
config SERIAL_BFIN_CONSOLE
720
	bool "Console on Blackfin serial port"
721
	depends on SERIAL_BFIN=y
722
	select SERIAL_CORE_CONSOLE
723
724
choice
725
	prompt "UART Mode"
726
	depends on SERIAL_BFIN
727
	default SERIAL_BFIN_DMA
728
	help
729
	  This driver supports the built-in serial ports of the Blackfin family
730
	  of CPUs
731
732
config SERIAL_BFIN_DMA
733
	bool "DMA mode"
734
	depends on !DMA_UNCACHED_NONE && KGDB_SERIAL_CONSOLE=n
735
	help
736
	  This driver works under DMA mode. If this option is selected, the
737
	  blackfin simple dma driver is also enabled.
738
739
config SERIAL_BFIN_PIO
740
	bool "PIO mode"
741
	help
742
	  This driver works under PIO mode.
743
744
endchoice
745
746
config SERIAL_BFIN_UART0
747
	bool "Enable UART0"
748
	depends on SERIAL_BFIN
749
	help
750
	  Enable UART0
751
752
config BFIN_UART0_CTSRTS
753
	bool "Enable UART0 hardware flow control"
754
	depends on SERIAL_BFIN_UART0
755
	help
756
	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
757
	  signal.
758
759
config UART0_CTS_PIN
760
	int "UART0 CTS pin"
761
	depends on BFIN_UART0_CTSRTS && !BF548
762
	default 23
763
	help
764
	  The default pin is GPIO_GP7.
765
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
766
767
config UART0_RTS_PIN
768
	int "UART0 RTS pin"
769
	depends on BFIN_UART0_CTSRTS && !BF548
770
	default 22
771
	help
772
	  The default pin is GPIO_GP6.
773
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
774
775
config SERIAL_BFIN_UART1
776
	bool "Enable UART1"
777
	depends on SERIAL_BFIN && (!BF531 && !BF532 && !BF533 && !BF561)
778
	help
779
	  Enable UART1
780
781
config BFIN_UART1_CTSRTS
782
	bool "Enable UART1 hardware flow control"
783
	depends on SERIAL_BFIN_UART1
784
	help
785
	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
786
	  signal.
787
788
config UART1_CTS_PIN
789
	int "UART1 CTS pin"
790
	depends on BFIN_UART1_CTSRTS && !BF548
791
	default -1
792
	help
793
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
794
795
config UART1_RTS_PIN
796
	int "UART1 RTS pin"
797
	depends on BFIN_UART1_CTSRTS && !BF548
798
	default -1
799
	help
800
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
801
802
config SERIAL_BFIN_UART2
803
	bool "Enable UART2"
804
	depends on SERIAL_BFIN && (BF54x || BF538 || BF539)
805
	help
806
	  Enable UART2
807
808
config BFIN_UART2_CTSRTS
809
	bool "Enable UART2 hardware flow control"
810
	depends on SERIAL_BFIN_UART2
811
	help
812
	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
813
	  signal.
814
815
config UART2_CTS_PIN
816
	int "UART2 CTS pin"
817
	depends on BFIN_UART2_CTSRTS && !BF548
818
	default -1
819
	help
820
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
821
822
config UART2_RTS_PIN
823
	int "UART2 RTS pin"
824
	depends on BFIN_UART2_CTSRTS && !BF548
825
	default -1
826
	help
827
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
828
829
config SERIAL_BFIN_UART3
830
	bool "Enable UART3"
831
	depends on SERIAL_BFIN && (BF54x)
832
	help
833
	  Enable UART3
834
835
config BFIN_UART3_CTSRTS
836
	bool "Enable UART3 hardware flow control"
837
	depends on SERIAL_BFIN_UART3
838
	help
839
	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
840
	  signal.
841
842
config UART3_CTS_PIN
843
	int "UART3 CTS pin"
844
	depends on BFIN_UART3_CTSRTS && !BF548
845
	default -1
846
	help
847
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
848
849
config UART3_RTS_PIN
850
	int "UART3 RTS pin"
851
	depends on BFIN_UART3_CTSRTS && !BF548
852
	default -1
853
	help
854
	  Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
855
856
config SERIAL_IMX
857
	bool "IMX serial port support"
858
	depends on ARM && (ARCH_IMX || ARCH_MXC)
859
	select SERIAL_CORE
860
	select RATIONAL
861
	help
862
	  If you have a machine based on a Motorola IMX CPU you
863
	  can enable its onboard serial port by enabling this option.
864
865
config SERIAL_IMX_CONSOLE
866
	bool "Console on IMX serial port"
867
	depends on SERIAL_IMX
868
	select SERIAL_CORE_CONSOLE
869
	help
870
	  If you have enabled the serial port on the Motorola IMX
871
	  CPU you can make it the console by answering Y to this option.
872
873
	  Even if you say Y here, the currently visible virtual console
874
	  (/dev/tty0) will still be used as the system console by default, but
875
	  you can alter that using a kernel command line option such as
876
	  "console=ttySA0". (Try "man bootparam" or see the documentation of
877
	  your boot loader (lilo or loadlin) about how to pass options to the
878
	  kernel at boot time.)
879
880
config SERIAL_UARTLITE
881
	tristate "Xilinx uartlite serial port support"
882
	depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE
883
	select SERIAL_CORE
884
	help
885
	  Say Y here if you want to use the Xilinx uartlite serial controller.
886
887
	  To compile this driver as a module, choose M here: the
888
	  module will be called uartlite.
889
890
config SERIAL_UARTLITE_CONSOLE
891
	bool "Support for console on Xilinx uartlite serial port"
892
	depends on SERIAL_UARTLITE=y
893
	select SERIAL_CORE_CONSOLE
894
	help
895
	  Say Y here if you wish to use a Xilinx uartlite as the system
896
	  console (the system console is the device which receives all kernel
897
	  messages and warnings and which allows logins in single user mode).
898
899
config SERIAL_SUNCORE
900
	bool
901
	depends on SPARC
902
	select SERIAL_CORE
903
	select SERIAL_CORE_CONSOLE
904
	default y
905
906
config SERIAL_SUNZILOG
907
	tristate "Sun Zilog8530 serial support"
908
	depends on SPARC
909
	help
910
	  This driver supports the Zilog8530 serial ports found on many Sparc
911
	  systems.  Say Y or M if you want to be able to these serial ports.
912
913
config SERIAL_SUNZILOG_CONSOLE
914
	bool "Console on Sun Zilog8530 serial port"
915
	depends on SERIAL_SUNZILOG=y
916
	help
917
	  If you would like to be able to use the Zilog8530 serial port
918
	  on your Sparc system as the console, you can do so by answering
919
	  Y to this option.
920
921
config SERIAL_SUNSU
922
	tristate "Sun SU serial support"
923
	depends on SPARC && PCI
924
	help
925
	  This driver supports the 8250 serial ports that run the keyboard and
926
	  mouse on (PCI) UltraSPARC systems.  Say Y or M if you want to be able
927
	  to these serial ports.
928
929
config SERIAL_SUNSU_CONSOLE
930
	bool "Console on Sun SU serial port"
931
	depends on SERIAL_SUNSU=y
932
	help
933
	  If you would like to be able to use the SU serial port
934
	  on your Sparc system as the console, you can do so by answering
935
	  Y to this option.
936
937
config SERIAL_MUX
938
	tristate "Serial MUX support"
939
	depends on GSC
940
	select SERIAL_CORE
941
	default y
942
	---help---
943
	  Saying Y here will enable the hardware MUX serial driver for
944
	  the Nova, K class systems and D class with a 'remote control card'.
945
	  The hardware MUX is not 8250/16550 compatible therefore the
946
	  /dev/ttyB0 device is shared between the Serial MUX and the PDC
947
	  software console. The following steps need to be completed to use
948
	  the Serial MUX:
949
950
	    1. create the device entry (mknod /dev/ttyB0 c 11 0)
951
	    2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
952
	    3. Add device ttyB0 to /etc/securetty (if you want to log on as
953
		 root on this console.)
954
	    4. Change the kernel command console parameter to: console=ttyB0
955
956
config SERIAL_MUX_CONSOLE
957
	bool "Support for console on serial MUX"
958
	depends on SERIAL_MUX=y
959
	select SERIAL_CORE_CONSOLE
960
	default y
961
962
config PDC_CONSOLE
963
	bool "PDC software console support"
964
	depends on PARISC && !SERIAL_MUX && VT
965
	default n
966
	help
967
	  Saying Y here will enable the software based PDC console to be 
968
	  used as the system console.  This is useful for machines in 
969
	  which the hardware based console has not been written yet.  The
970
	  following steps must be competed to use the PDC console:
971
972
	    1. create the device entry (mknod /dev/ttyB0 c 11 0)
973
	    2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
974
	    3. Add device ttyB0 to /etc/securetty (if you want to log on as
975
		 root on this console.)
976
	    4. Change the kernel command console parameter to: console=ttyB0
977
978
config SERIAL_SUNSAB
979
	tristate "Sun Siemens SAB82532 serial support"
980
	depends on SPARC && PCI
981
	help
982
	  This driver supports the Siemens SAB82532 DUSCC serial ports on newer
983
	  (PCI) UltraSPARC systems.  Say Y or M if you want to be able to these
984
	  serial ports.
985
986
config SERIAL_SUNSAB_CONSOLE
987
	bool "Console on Sun Siemens SAB82532 serial port"
988
	depends on SERIAL_SUNSAB=y
989
	help
990
	  If you would like to be able to use the SAB82532 serial port
991
	  on your Sparc system as the console, you can do so by answering
992
	  Y to this option.
993
994
config SERIAL_SUNHV
995
	bool "Sun4v Hypervisor Console support"
996
	depends on SPARC64
997
	help
998
	  This driver supports the console device found on SUN4V Sparc
999
	  systems.  Say Y if you want to be able to use this device.
1000
1001
config SERIAL_IP22_ZILOG
1002
	tristate "SGI Zilog8530 serial support"
1003
	depends on SGI_HAS_ZILOG
1004
	select SERIAL_CORE
1005
	help
1006
	  This driver supports the Zilog8530 serial ports found on SGI
1007
	  systems.  Say Y or M if you want to be able to these serial ports.
1008
1009
config SERIAL_IP22_ZILOG_CONSOLE
1010
	bool "Console on SGI Zilog8530 serial port"
1011
	depends on SERIAL_IP22_ZILOG=y
1012
	select SERIAL_CORE_CONSOLE
1013
1014
config SERIAL_SH_SCI
1015
	tristate "SuperH SCI(F) serial port support"
1016
	depends on HAVE_CLK && (SUPERH || H8300)
1017
	select SERIAL_CORE
1018
1019
config SERIAL_SH_SCI_NR_UARTS
1020
	int "Maximum number of SCI(F) serial ports"
1021
	depends on SERIAL_SH_SCI
1022
	default "2"
1023
1024
config SERIAL_SH_SCI_CONSOLE
1025
	bool "Support for console on SuperH SCI(F)"
1026
	depends on SERIAL_SH_SCI=y
1027
	select SERIAL_CORE_CONSOLE
1028
1029
config SERIAL_PNX8XXX
1030
	bool "Enable PNX8XXX SoCs' UART Support"
1031
	depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
1032
	select SERIAL_CORE
1033
	help
1034
	  If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
1035
	  and you want to use serial ports, say Y.  Otherwise, say N.
1036
1037
config SERIAL_PNX8XXX_CONSOLE
1038
	bool "Enable PNX8XX0 serial console"
1039
	depends on SERIAL_PNX8XXX
1040
	select SERIAL_CORE_CONSOLE
1041
	help
1042
	  If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
1043
	  and you want to use serial console, say Y. Otherwise, say N.
1044
1045
config SERIAL_CORE
1046
	tristate
1047
1048
config SERIAL_CORE_CONSOLE
1049
	bool
1050
1051
config CONSOLE_POLL
1052
	bool
1053
1054
config SERIAL_68328
1055
	bool "68328 serial support"
1056
	depends on M68328 || M68EZ328 || M68VZ328
1057
	help
1058
	  This driver supports the built-in serial port of the Motorola 68328
1059
	  (standard, EZ and VZ varieties).
1060
1061
config SERIAL_68328_RTS_CTS
1062
	bool "Support RTS/CTS on 68328 serial port"
1063
	depends on SERIAL_68328
1064
1065
config SERIAL_MCF
1066
	bool "Coldfire serial support"
1067
	depends on COLDFIRE
1068
	select SERIAL_CORE
1069
	help
1070
	  This serial driver supports the Freescale Coldfire serial ports.
1071
1072
config SERIAL_MCF_BAUDRATE
1073
	int "Default baudrate for Coldfire serial ports"
1074
	depends on SERIAL_MCF
1075
	default 19200
1076
	help
1077
	  This setting lets you define what the default baudrate is for the
1078
	  ColdFire serial ports. The usual default varies from board to board,
1079
	  and this setting is a way of catering for that.
1080
1081
config SERIAL_MCF_CONSOLE
1082
	bool "Coldfire serial console support"
1083
	depends on SERIAL_MCF
1084
	select SERIAL_CORE_CONSOLE
1085
	help
1086
	  Enable a ColdFire internal serial port to be the system console.
1087
1088
config SERIAL_68360_SMC
1089
	bool "68360 SMC uart support"
1090
	depends on M68360
1091
	help
1092
	  This driver supports the SMC serial ports of the Motorola 68360 CPU.
1093
1094
config SERIAL_68360_SCC
1095
	bool "68360 SCC uart support"
1096
	depends on M68360
1097
	help
1098
	  This driver supports the SCC serial ports of the Motorola 68360 CPU.
1099
1100
config SERIAL_68360
1101
	bool
1102
	depends on SERIAL_68360_SMC || SERIAL_68360_SCC
1103
	default y
1104
1105
config SERIAL_PMACZILOG
1106
	tristate "PowerMac z85c30 ESCC support"
1107
	depends on PPC_OF && PPC_PMAC
1108
	select SERIAL_CORE
1109
	help
1110
	  This driver supports the Zilog z85C30 serial ports found on
1111
	  PowerMac machines.
1112
	  Say Y or M if you want to be able to these serial ports.
1113
1114
config SERIAL_PMACZILOG_TTYS
1115
	bool "Use ttySn device nodes for Zilog z85c30"
1116
	depends on SERIAL_PMACZILOG
1117
	help
1118
	  The pmac_zilog driver for the z85C30 chip on many powermacs
1119
	  historically used the device numbers for /dev/ttySn.  The
1120
	  8250 serial port driver also uses these numbers, which means
1121
	  the two drivers being unable to coexist; you could not use
1122
	  both z85C30 and 8250 type ports at the same time.
1123
1124
	  If this option is not selected, the pmac_zilog driver will
1125
	  use the device numbers allocated for /dev/ttyPZn.  This allows
1126
	  the pmac_zilog and 8250 drivers to co-exist, but may cause
1127
	  existing userspace setups to break.  Programs that need to
1128
	  access the built-in serial ports on powermacs will need to
1129
	  be reconfigured to use /dev/ttyPZn instead of /dev/ttySn.
1130
1131
	  If you enable this option, any z85c30 ports in the system will
1132
	  be registered as ttyS0 onwards as in the past, and you will be
1133
	  unable to use the 8250 module for PCMCIA or other 16C550-style
1134
	  UARTs.
1135
1136
	  Say N unless you need the z85c30 ports on your powermac
1137
	  to appear as /dev/ttySn.
1138
1139
config SERIAL_PMACZILOG_CONSOLE
1140
	bool "Console on PowerMac z85c30 serial port"
1141
	depends on SERIAL_PMACZILOG=y
1142
	select SERIAL_CORE_CONSOLE
1143
	help
1144
	  If you would like to be able to use the z85c30 serial port
1145
	  on your PowerMac as the console, you can do so by answering
1146
	  Y to this option.
1147
1148
config SERIAL_LH7A40X
1149
	tristate "Sharp LH7A40X embedded UART support"
1150
	depends on ARM && ARCH_LH7A40X
1151
	select SERIAL_CORE
1152
	help
1153
	  This enables support for the three on-board UARTs of the
1154
	  Sharp LH7A40X series CPUs.  Choose Y or M.
1155
1156
config SERIAL_LH7A40X_CONSOLE
1157
	bool "Support for console on Sharp LH7A40X serial port"
1158
	depends on SERIAL_LH7A40X=y
1159
	select SERIAL_CORE_CONSOLE
1160
	help
1161
	  Say Y here if you wish to use one of the serial ports as the
1162
	  system console--the system console is the device which
1163
	  receives all kernel messages and warnings and which allows
1164
	  logins in single user mode.
1165
1166
	  Even if you say Y here, the currently visible framebuffer console
1167
	  (/dev/tty0) will still be used as the default system console, but
1168
	  you can alter that using a kernel command line, for example
1169
	  "console=ttyAM1".
1170
1171
config SERIAL_CPM
1172
	tristate "CPM SCC/SMC serial port support"
1173
	depends on CPM2 || 8xx
1174
	select SERIAL_CORE
1175
	help
1176
	  This driver supports the SCC and SMC serial ports on Motorola 
1177
	  embedded PowerPC that contain a CPM1 (8xx) or CPM2 (8xxx)
1178
1179
config SERIAL_CPM_CONSOLE
1180
	bool "Support for console on CPM SCC/SMC serial port"
1181
	depends on SERIAL_CPM=y
1182
	select SERIAL_CORE_CONSOLE
1183
	help
1184
	  Say Y here if you wish to use a SCC or SMC CPM UART as the system
1185
	  console (the system console is the device which receives all kernel
1186
	  messages and warnings and which allows logins in single user mode).
1187
1188
	  Even if you say Y here, the currently visible framebuffer console
1189
	  (/dev/tty0) will still be used as the system console by default, but
1190
	  you can alter that using a kernel command line option such as
1191
	  "console=ttyCPM0". (Try "man bootparam" or see the documentation of
1192
	  your boot loader (lilo or loadlin) about how to pass options to the
1193
	  kernel at boot time.)
1194
1195
config SERIAL_SGI_L1_CONSOLE
1196
	bool "SGI Altix L1 serial console support"
1197
	depends on IA64_GENERIC || IA64_SGI_SN2
1198
	select SERIAL_CORE
1199
	select SERIAL_CORE_CONSOLE
1200
	help
1201
		If you have an SGI Altix and you would like to use the system
1202
		controller serial port as your console (you want this!),
1203
		say Y.  Otherwise, say N.
1204
1205
config SERIAL_MPC52xx
1206
	tristate "Freescale MPC52xx/MPC512x family PSC serial support"
1207
	depends on PPC_MPC52xx || PPC_MPC512x
1208
	select SERIAL_CORE
1209
	help
1210
	  This driver supports MPC52xx and MPC512x PSC serial ports. If you would
1211
	  like to use them, you must answer Y or M to this option. Note that
1212
	  for use as console, it must be included in kernel and not as a
1213
	  module.
1214
1215
config SERIAL_MPC52xx_CONSOLE
1216
	bool "Console on a Freescale MPC52xx/MPC512x family PSC serial port"
1217
	depends on SERIAL_MPC52xx=y
1218
	select SERIAL_CORE_CONSOLE
1219
	help
1220
	  Select this options if you'd like to use one of the PSC serial port
1221
	  of the Freescale MPC52xx family as a console.
1222
1223
config SERIAL_MPC52xx_CONSOLE_BAUD
1224
	int "Freescale MPC52xx/MPC512x family PSC serial port baud"
1225
	depends on SERIAL_MPC52xx_CONSOLE=y
1226
	default "9600"
1227
	help
1228
	  Select the MPC52xx console baud rate.
1229
	  This value is only used if the bootloader doesn't pass in the
1230
	  console baudrate
1231
1232
config SERIAL_ICOM
1233
	tristate "IBM Multiport Serial Adapter"
1234
	depends on PCI && (PPC_ISERIES || PPC_PSERIES)
1235
	select SERIAL_CORE
1236
	select FW_LOADER
1237
	help
1238
	  This driver is for a family of multiport serial adapters
1239
	  including 2 port RVX, 2 port internal modem, 4 port internal
1240
	  modem and a split 1 port RVX and 1 port internal modem.
1241
1242
	  This driver can also be built as a module.  If so, the module
1243
	  will be called icom.
1244
1245
config SERIAL_M32R_SIO
1246
	bool "M32R SIO I/F"
1247
	depends on M32R
1248
	default y
1249
	select SERIAL_CORE
1250
	help
1251
	  Say Y here if you want to use the M32R serial controller.
1252
1253
config SERIAL_M32R_SIO_CONSOLE
1254
	bool "use SIO console"
1255
	depends on SERIAL_M32R_SIO=y
1256
	select SERIAL_CORE_CONSOLE
1257
	help
1258
	  Say Y here if you want to support a serial console.
1259
1260
	  If you use an M3T-M32700UT or an OPSPUT platform,
1261
	  please say also y for SERIAL_M32R_PLDSIO.
1262
1263
config SERIAL_M32R_PLDSIO
1264
	bool "M32R SIO I/F on a PLD"
1265
	depends on SERIAL_M32R_SIO=y && (PLAT_OPSPUT || PLAT_USRV || PLAT_M32700UT)
1266
	default n
1267
	help
1268
	  Say Y here if you want to use the M32R serial controller
1269
	  on a PLD (Programmable Logic Device).
1270
1271
	  If you use an M3T-M32700UT or an OPSPUT platform,
1272
	  please say Y.
1273
1274
config SERIAL_TXX9
1275
	bool "TMPTX39XX/49XX SIO support"
1276
	depends on HAS_TXX9_SERIAL
1277
	select SERIAL_CORE
1278
	default y
1279
1280
config HAS_TXX9_SERIAL
1281
	bool
1282
1283
config SERIAL_TXX9_NR_UARTS
1284
	int "Maximum number of TMPTX39XX/49XX SIO ports"
1285
	depends on SERIAL_TXX9
1286
	default "6"
1287
1288
config SERIAL_TXX9_CONSOLE
1289
	bool "TMPTX39XX/49XX SIO Console support"
1290
	depends on SERIAL_TXX9=y
1291
	select SERIAL_CORE_CONSOLE
1292
1293
config SERIAL_TXX9_STDSERIAL
1294
	bool "TX39XX/49XX SIO act as standard serial"
1295
	depends on !SERIAL_8250 && SERIAL_TXX9
1296
1297
config SERIAL_VR41XX
1298
	tristate "NEC VR4100 series Serial Interface Unit support"
1299
	depends on CPU_VR41XX
1300
	select SERIAL_CORE
1301
	help
1302
	  If you have a NEC VR4100 series processor and you want to use
1303
	  Serial Interface Unit(SIU) or Debug Serial Interface Unit(DSIU)
1304
	  (not include VR4111/VR4121 DSIU), say Y.  Otherwise, say N.
1305
1306
config SERIAL_VR41XX_CONSOLE
1307
	bool "Enable NEC VR4100 series Serial Interface Unit console"
1308
	depends on SERIAL_VR41XX=y
1309
	select SERIAL_CORE_CONSOLE
1310
	help
1311
	  If you have a NEC VR4100 series processor and you want to use
1312
	  a console on a serial port, say Y.  Otherwise, say N.
1313
1314
config SERIAL_JSM
1315
	tristate "Digi International NEO PCI Support"
1316
	depends on PCI
1317
	select SERIAL_CORE
1318
	help
1319
	  This is a driver for Digi International's Neo series
1320
	  of cards which provide multiple serial ports. You would need
1321
	  something like this to connect more than two modems to your Linux
1322
	  box, for instance in order to become a dial-in server. This driver
1323
	  supports PCI boards only.
1324
1325
	  If you have a card like this, say Y here, otherwise say N.
1326
1327
	  To compile this driver as a module, choose M here: the
1328
	  module will be called jsm.
1329
1330
config SERIAL_SGI_IOC4
1331
	tristate "SGI IOC4 controller serial support"
1332
	depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC4
1333
	select SERIAL_CORE
1334
	help
1335
		If you have an SGI Altix with an IOC4 based Base IO card
1336
		and wish to use the serial ports on this card, say Y.
1337
		Otherwise, say N.
1338
1339
config SERIAL_SGI_IOC3
1340
	tristate "SGI Altix IOC3 serial support"
1341
	depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC3
1342
	select SERIAL_CORE
1343
	help
1344
	  If you have an SGI Altix with an IOC3 serial card,
1345
	  say Y or M.  Otherwise, say N.
1346
1347
config SERIAL_MSM
1348
	bool "MSM on-chip serial port support"
1349
	depends on ARM && ARCH_MSM
1350
	select SERIAL_CORE
1351
1352
config SERIAL_MSM_CONSOLE
1353
	bool "MSM serial console support"
1354
	depends on SERIAL_MSM=y
1355
	select SERIAL_CORE_CONSOLE
1356
1357
config SERIAL_NETX
1358
	tristate "NetX serial port support"
1359
	depends on ARM && ARCH_NETX
1360
	select SERIAL_CORE
1361
	help
1362
	  If you have a machine based on a Hilscher NetX SoC you
1363
	  can enable its onboard serial port by enabling this option.
1364
1365
          To compile this driver as a module, choose M here: the
1366
          module will be called netx-serial.
1367
1368
config SERIAL_NETX_CONSOLE
1369
	bool "Console on NetX serial port"
1370
	depends on SERIAL_NETX=y
1371
	select SERIAL_CORE_CONSOLE
1372
	help
1373
	  If you have enabled the serial port on the Hilscher NetX SoC
1374
	  you can make it the console by answering Y to this option.
1375
1376
config SERIAL_OF_PLATFORM
1377
	tristate "Serial port on Open Firmware platform bus"
1378
	depends on PPC_OF || MICROBLAZE
1379
	depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL
1380
	help
1381
	  If you have a PowerPC based system that has serial ports
1382
	  on a platform specific bus, you should enable this option.
1383
	  Currently, only 8250 compatible ports are supported, but
1384
	  others can easily be added.
1385
1386
config SERIAL_OF_PLATFORM_NWPSERIAL
1387
	tristate "NWP serial port driver"
1388
	depends on PPC_OF && PPC_DCR
1389
	select SERIAL_OF_PLATFORM
1390
	select SERIAL_CORE_CONSOLE
1391
	select SERIAL_CORE
1392
	help
1393
	  This driver supports the cell network processor nwp serial
1394
	  device.
1395
1396
config SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE
1397
	bool "Console on NWP serial port"
1398
	depends on SERIAL_OF_PLATFORM_NWPSERIAL=y
1399
	select SERIAL_CORE_CONSOLE
1400
	help
1401
	  Support for Console on the NWP serial ports.
1402
1403
config SERIAL_QE
1404
	tristate "Freescale QUICC Engine serial port support"
1405
	depends on QUICC_ENGINE
1406
	select SERIAL_CORE
1407
	select FW_LOADER
1408
	default n
1409
	help
1410
	  This driver supports the QE serial ports on Freescale embedded
1411
	  PowerPC that contain a QUICC Engine.
1412
1413
config SERIAL_SC26XX
1414
	tristate "SC2681/SC2692 serial port support"
1415
	depends on SNI_RM
1416
	select SERIAL_CORE
1417
	help
1418
	  This is a driver for the onboard serial ports of
1419
	  older RM400 machines.
1420
1421
config SERIAL_SC26XX_CONSOLE
1422
	bool "Console on SC2681/SC2692 serial port"
1423
	depends on SERIAL_SC26XX
1424
	select SERIAL_CORE_CONSOLE
1425
	help
1426
	  Support for Console on SC2681/SC2692 serial ports.
1427
1428
config SERIAL_BFIN_SPORT
1429
	tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)"
1430
	depends on BLACKFIN && EXPERIMENTAL
1431
	select SERIAL_CORE
1432
	help
1433
	  Enable SPORT emulate UART on Blackfin series.
1434
1435
	  To compile this driver as a module, choose M here: the
1436
	  module will be called bfin_sport_uart.
1437
1438
choice
1439
	prompt "Baud rate for Blackfin SPORT UART"
1440
	depends on SERIAL_BFIN_SPORT
1441
	default SERIAL_SPORT_BAUD_RATE_57600
1442
	help
1443
	  Choose a baud rate for the SPORT UART, other uart settings are
1444
	  8 bit, 1 stop bit, no parity, no flow control.
1445
1446
config SERIAL_SPORT_BAUD_RATE_115200
1447
	bool "115200"
1448
1449
config SERIAL_SPORT_BAUD_RATE_57600
1450
	bool "57600"
1451
1452
config SERIAL_SPORT_BAUD_RATE_38400
1453
	bool "38400"
1454
1455
config SERIAL_SPORT_BAUD_RATE_19200
1456
	bool "19200"
1457
1458
config SERIAL_SPORT_BAUD_RATE_9600
1459
	bool "9600"
1460
endchoice
1461
1462
config SPORT_BAUD_RATE
1463
	int
1464
	depends on SERIAL_BFIN_SPORT
1465
	default 115200 if (SERIAL_SPORT_BAUD_RATE_115200)
1466
	default 57600 if (SERIAL_SPORT_BAUD_RATE_57600)
1467
	default 38400 if (SERIAL_SPORT_BAUD_RATE_38400)
1468
	default 19200 if (SERIAL_SPORT_BAUD_RATE_19200)
1469
	default 9600 if (SERIAL_SPORT_BAUD_RATE_9600)
1470
1471
config SERIAL_TIMBERDALE
1472
	tristate "Support for timberdale UART"
1473
	depends on MFD_TIMBERDALE
1474
	select SERIAL_CORE
1475
	---help---
1476
	Add support for UART controller on timberdale.
1477
1478
config SERIAL_BCM63XX
1479
	tristate "bcm63xx serial port support"
1480
	select SERIAL_CORE
1481
	depends on BCM63XX
1482
	help
1483
	  If you have a bcm63xx CPU, you can enable its onboard
1484
	  serial port by enabling this options.
1485
1486
          To compile this driver as a module, choose M here: the
1487
          module will be called bcm963xx_uart.
1488
1489
config SERIAL_BCM63XX_CONSOLE
1490
	bool "Console on bcm63xx serial port"
1491
	depends on SERIAL_BCM63XX=y
1492
	select SERIAL_CORE_CONSOLE
1493
	help
1494
	  If you have enabled the serial port on the bcm63xx CPU
1495
	  you can make it the console by answering Y to this option.
1496
1497
config SERIAL_GRLIB_GAISLER_APBUART
1498
	tristate "GRLIB APBUART serial support"
1499
	depends on OF
1500
	---help---
1501
	Add support for the GRLIB APBUART serial port.
1502
1503
config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
1504
	bool "Console on GRLIB APBUART serial port"
1505
	depends on SERIAL_GRLIB_GAISLER_APBUART=y
1506
	select SERIAL_CORE_CONSOLE
1507
	help
1508
	Support for running a console on the GRLIB APBUART
1509
1510
endmenu
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/drivers/serial/Makefile (+87 lines)
Line 0    Link Here 
1
#
2
# Makefile for the kernel serial device drivers.
3
#
4
5
obj-$(CONFIG_SERIAL_CORE) += serial_core.o
6
obj-$(CONFIG_SERIAL_21285) += 21285.o
7
8
# These Sparc drivers have to appear before others such as 8250
9
# which share ttySx minor node space.  Otherwise console device
10
# names change and other unplesantries.
11
obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
12
obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
13
obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
14
obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
15
obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
16
17
obj-$(CONFIG_SERIAL_8250) += 8250.o
18
obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
19
obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
20
obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
21
obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
22
obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
23
obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
24
obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
25
obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
26
obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
27
obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
28
obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
29
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
30
obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
31
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
32
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
33
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
34
obj-$(CONFIG_SERIAL_PXA) += pxa.o
35
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
36
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
37
obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
38
obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
39
obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
40
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
41
obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o
42
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
43
obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
44
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
45
obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
46
obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
47
obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
48
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
49
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
50
obj-$(CONFIG_SERIAL_MUX) += mux.o
51
obj-$(CONFIG_SERIAL_68328) += 68328serial.o
52
obj-$(CONFIG_SERIAL_68360) += 68360serial.o
53
obj-$(CONFIG_SERIAL_MCF) += mcf.o
54
obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
55
obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
56
obj-$(CONFIG_SERIAL_DZ) += dz.o
57
obj-$(CONFIG_SERIAL_ZS) += zs.o
58
obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
59
obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o
60
obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
61
obj-$(CONFIG_SERIAL_IMX) += imx.o
62
obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
63
obj-$(CONFIG_SERIAL_ICOM) += icom.o
64
obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o
65
obj-$(CONFIG_SERIAL_MPSC) += mpsc.o
66
obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o
67
obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
68
obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o
69
obj-$(CONFIG_SERIAL_JSM) += jsm/
70
obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
71
obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
72
obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
73
obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
74
obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
75
obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
76
obj-$(CONFIG_SERIAL_MSM) += msm_serial.o
77
obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
78
obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
79
obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o
80
obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
81
obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
82
obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
83
obj-$(CONFIG_SERIAL_TIMBERDALE)	+= timbuart.o
84
obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
85
obj-$(CONFIG_SERIAL_RDPUART) += rdptty.o
86
87
rdptty-objs := rdp.o rdpmain.o
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/drivers/serial/ntddser.h (+404 lines)
Line 0    Link Here 
1
/*
2
 * DDK definitions for serial port
3
 *
4
 * Copyright (C) 2006 Eric Pouech
5
 * From w32api package
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
 */
21
22
#ifndef _NTDDSER_H_
23
#define _NTDDSER_H_
24
25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28
29
#define IOCTL_SERIAL_CLEAR_STATS                                        \
30
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 36, METHOD_BUFFERED, FILE_ANY_ACCESS)
31
#define IOCTL_SERIAL_CLR_DTR                                            \
32
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
33
#define IOCTL_SERIAL_CLR_RTS                                            \
34
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
35
#define IOCTL_SERIAL_CONFIG_SIZE                                        \
36
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 32, METHOD_BUFFERED, FILE_ANY_ACCESS)
37
#define IOCTL_SERIAL_GET_BAUD_RATE                                      \
38
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 20, METHOD_BUFFERED, FILE_ANY_ACCESS)
39
#define IOCTL_SERIAL_GET_CHARS                                          \
40
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 22, METHOD_BUFFERED, FILE_ANY_ACCESS)
41
#define IOCTL_SERIAL_GET_COMMSTATUS                                     \
42
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 27, METHOD_BUFFERED, FILE_ANY_ACCESS)
43
#define IOCTL_SERIAL_GET_DTRRTS                                         \
44
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 30, METHOD_BUFFERED, FILE_ANY_ACCESS)
45
#define IOCTL_SERIAL_GET_HANDFLOW                                       \
46
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 24, METHOD_BUFFERED, FILE_ANY_ACCESS)
47
#define IOCTL_SERIAL_GET_LINE_CONTROL                                   \
48
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 21, METHOD_BUFFERED, FILE_ANY_ACCESS)
49
#define IOCTL_SERIAL_GET_MODEM_CONTROL                                  \
50
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 37, METHOD_BUFFERED, FILE_ANY_ACCESS)
51
#define IOCTL_SERIAL_GET_MODEMSTATUS                                    \
52
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 26, METHOD_BUFFERED, FILE_ANY_ACCESS)
53
#define IOCTL_SERIAL_GET_PROPERTIES                                     \
54
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 29, METHOD_BUFFERED, FILE_ANY_ACCESS)
55
#define IOCTL_SERIAL_GET_STATS                                          \
56
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 35, METHOD_BUFFERED, FILE_ANY_ACCESS)
57
#define IOCTL_SERIAL_GET_TIMEOUTS                                       \
58
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
59
#define IOCTL_SERIAL_GET_WAIT_MASK                                      \
60
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 16, METHOD_BUFFERED, FILE_ANY_ACCESS)
61
#define IOCTL_SERIAL_IMMEDIATE_CHAR                                     \
62
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
63
#ifndef IOCTL_SERIAL_LSRMST_INSERT
64
/* it's already defined in winioctl.h */
65
#define IOCTL_SERIAL_LSRMST_INSERT                             \
66
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 31, METHOD_BUFFERED, FILE_ANY_ACCESS)
67
#endif
68
#define IOCTL_SERIAL_PURGE                                              \
69
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 19, METHOD_BUFFERED, FILE_ANY_ACCESS)
70
#define IOCTL_SERIAL_RESET_DEVICE                                       \
71
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 11, METHOD_BUFFERED, FILE_ANY_ACCESS)
72
#define IOCTL_SERIAL_SET_BAUD_RATE                                      \
73
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
74
#define IOCTL_SERIAL_SET_BREAK_ON                                       \
75
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 4, METHOD_BUFFERED, FILE_ANY_ACCESS)
76
#define IOCTL_SERIAL_SET_BREAK_OFF                                      \
77
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
78
#define IOCTL_SERIAL_SET_CHARS                                          \
79
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 23, METHOD_BUFFERED, FILE_ANY_ACCESS)
80
#define IOCTL_SERIAL_SET_DTR                                            \
81
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
82
#define IOCTL_SERIAL_SET_FIFO_CONTROL                                   \
83
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 39, METHOD_BUFFERED, FILE_ANY_ACCESS)
84
#define IOCTL_SERIAL_SET_HANDFLOW                                       \
85
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 25, METHOD_BUFFERED, FILE_ANY_ACCESS)
86
#define IOCTL_SERIAL_SET_LINE_CONTROL                                   \
87
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)
88
#define IOCTL_SERIAL_SET_MODEM_CONTROL                                  \
89
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 38, METHOD_BUFFERED, FILE_ANY_ACCESS)
90
#define IOCTL_SERIAL_SET_QUEUE_SIZE                                     \
91
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
92
#define IOCTL_SERIAL_SET_RTS                                            \
93
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
94
#define IOCTL_SERIAL_SET_TIMEOUTS                                       \
95
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
96
#define IOCTL_SERIAL_SET_WAIT_MASK                                      \
97
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 17, METHOD_BUFFERED, FILE_ANY_ACCESS)
98
#define IOCTL_SERIAL_SET_XOFF                                           \
99
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)
100
#define IOCTL_SERIAL_SET_XON                                            \
101
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
102
#define IOCTL_SERIAL_WAIT_ON_MASK                                       \
103
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)
104
#define IOCTL_SERIAL_XOFF_COUNTER                                       \
105
    CTL_CODE (FILE_DEVICE_SERIAL_PORT, 28, METHOD_BUFFERED, FILE_ANY_ACCESS)
106
107
typedef unsigned long		ULONG;
108
typedef long			LONG;
109
typedef unsigned char		UCHAR;
110
typedef unsigned short		USHORT;
111
typedef short			SHORT;
112
typedef unsigned short		WCHAR;
113
typedef UCHAR			BOOLEAN;
114
115
typedef struct _SERIAL_BAUD_RATE {
116
    ULONG       BaudRate;
117
} SERIAL_BAUD_RATE, *PSERIAL_BAUD_RATE;
118
119
/* SERIAL_BAUD_RATE.BaudRate constants */
120
#define SERIAL_BAUD_075                   0x00000001
121
#define SERIAL_BAUD_110                   0x00000002
122
#define SERIAL_BAUD_134_5                 0x00000004
123
#define SERIAL_BAUD_150                   0x00000008
124
#define SERIAL_BAUD_300                   0x00000010
125
#define SERIAL_BAUD_600                   0x00000020
126
#define SERIAL_BAUD_1200                  0x00000040
127
#define SERIAL_BAUD_1800                  0x00000080
128
#define SERIAL_BAUD_2400                  0x00000100
129
#define SERIAL_BAUD_4800                  0x00000200
130
#define SERIAL_BAUD_7200                  0x00000400
131
#define SERIAL_BAUD_9600                  0x00000800
132
#define SERIAL_BAUD_14400                 0x00001000
133
#define SERIAL_BAUD_19200                 0x00002000
134
#define SERIAL_BAUD_38400                 0x00004000
135
#define SERIAL_BAUD_56K                   0x00008000
136
#define SERIAL_BAUD_128K                  0x00010000
137
#define SERIAL_BAUD_115200                0x00020000
138
#define SERIAL_BAUD_57600                 0x00040000
139
#define SERIAL_BAUD_USER                  0x10000000
140
141
typedef struct _SERIAL_CHARS
142
{
143
    UCHAR       EofChar;
144
    UCHAR       ErrorChar;
145
    UCHAR       BreakChar;
146
    UCHAR       EventChar;
147
    UCHAR       XonChar;
148
    UCHAR       XoffChar;
149
} SERIAL_CHARS, *PSERIAL_CHARS;
150
151
typedef struct _SERIAL_STATUS
152
{
153
    ULONG	Errors;
154
    ULONG	HoldReasons;
155
    ULONG	AmountInInQueue;
156
    ULONG	AmountInOutQueue;
157
    UCHAR	EofReceived;
158
    UCHAR	WaitForImmediate;
159
} SERIAL_STATUS, *PSERIAL_STATUS;
160
161
typedef struct _SERIAL_HANDFLOW
162
{
163
    ULONG       ControlHandShake;
164
    ULONG       FlowReplace;
165
    LONG        XonLimit;
166
    LONG        XoffLimit;
167
} SERIAL_HANDFLOW, *PSERIAL_HANDFLOW;
168
169
#define SERIAL_DTR_MASK                   0x00000003
170
#define SERIAL_DTR_CONTROL                0x00000001
171
#define SERIAL_DTR_HANDSHAKE              0x00000002
172
#define SERIAL_CTS_HANDSHAKE              0x00000008
173
#define SERIAL_DSR_HANDSHAKE              0x00000010
174
#define SERIAL_DCD_HANDSHAKE              0x00000020
175
#define SERIAL_OUT_HANDSHAKEMASK          0x00000038
176
#define SERIAL_DSR_SENSITIVITY            0x00000040
177
#define SERIAL_ERROR_ABORT                0x80000000
178
#define SERIAL_CONTROL_INVALID            0x7fffff84
179
#define SERIAL_AUTO_TRANSMIT              0x00000001
180
#define SERIAL_AUTO_RECEIVE               0x00000002
181
#define SERIAL_ERROR_CHAR                 0x00000004
182
#define SERIAL_NULL_STRIPPING             0x00000008
183
#define SERIAL_BREAK_CHAR                 0x00000010
184
#define SERIAL_RTS_MASK                   0x000000c0
185
#define SERIAL_RTS_CONTROL                0x00000040
186
#define SERIAL_RTS_HANDSHAKE              0x00000080
187
#define SERIAL_TRANSMIT_TOGGLE            0x000000c0
188
#define SERIAL_XOFF_CONTINUE              0x80000000
189
#define SERIAL_FLOW_INVALID               0x7fffff20
190
191
typedef struct _SERIAL_LINE_CONTROL {
192
    UCHAR       StopBits;
193
    UCHAR       Parity;
194
    UCHAR       WordLength;
195
} SERIAL_LINE_CONTROL, *PSERIAL_LINE_CONTROL;
196
197
/* SERIAL_LINE_CONTROL.StopBits constants */
198
#define STOP_BIT_1                        0x00
199
#define STOP_BITS_1_5                     0x01
200
#define STOP_BITS_2                       0x02
201
202
/* SERIAL_LINE_CONTROL.Parity constants */
203
#define NO_PARITY                         0x00
204
#define ODD_PARITY                        0x01
205
#define EVEN_PARITY                       0x02
206
#define MARK_PARITY                       0x03
207
#define SPACE_PARITY                      0x04
208
209
/* IOCTL_SERIAL_(GET_MODEM_CONTROL, SET_MODEM_CONTROL) flags */
210
#define SERIAL_IOC_MCR_DTR                0x00000001
211
#define SERIAL_IOC_MCR_RTS                0x00000002
212
#define SERIAL_IOC_MCR_OUT1               0x00000004
213
#define SERIAL_IOC_MCR_OUT2               0x00000008
214
#define SERIAL_IOC_MCR_LOOP               0x00000010
215
216
typedef struct _SERIAL_COMMPROP
217
{
218
    USHORT      PacketLength;
219
    USHORT      PacketVersion;
220
    ULONG       ServiceMask;
221
    ULONG       Reserved1;
222
    ULONG       MaxTxQueue;
223
    ULONG       MaxRxQueue;
224
    ULONG       MaxBaud;
225
    ULONG       ProvSubType;
226
    ULONG       ProvCapabilities;
227
    ULONG       SettableParams;
228
    ULONG       SettableBaud;
229
    USHORT      SettableData;
230
    USHORT      SettableStopParity;
231
    ULONG       CurrentTxQueue;
232
    ULONG       CurrentRxQueue;
233
    ULONG       ProvSpec1;
234
    ULONG       ProvSpec2;
235
    WCHAR       ProvChar[1];
236
} SERIAL_COMMPROP, *PSERIAL_COMMPROP;
237
238
/* SERIAL_COMMPROP.SettableParams flags */
239
#define SERIAL_SP_PARITY                  0x0001
240
#define SERIAL_SP_BAUD                    0x0002
241
#define SERIAL_SP_DATABITS                0x0004
242
#define SERIAL_SP_STOPBITS                0x0008
243
#define SERIAL_SP_HANDSHAKING             0x0010
244
#define SERIAL_SP_PARITY_CHECK            0x0020
245
#define SERIAL_SP_CARRIER_DETECT          0x0040
246
247
/* SERIAL_COMMPROP.ProvCapabilities flags */
248
#define SERIAL_PCF_DTRDSR                 0x00000001
249
#define SERIAL_PCF_RTSCTS                 0x00000002
250
#define SERIAL_PCF_CD                     0x00000004
251
#define SERIAL_PCF_PARITY_CHECK           0x00000008
252
#define SERIAL_PCF_XONXOFF                0x00000010
253
#define SERIAL_PCF_SETXCHAR               0x00000020
254
#define SERIAL_PCF_TOTALTIMEOUTS          0x00000040
255
#define SERIAL_PCF_INTTIMEOUTS            0x00000080
256
#define SERIAL_PCF_SPECIALCHARS           0x00000100
257
#define SERIAL_PCF_16BITMODE              0x00000200
258
259
/* SERIAL_COMMPROP.SettableData flags */
260
#define SERIAL_DATABITS_5                 0x0001
261
#define SERIAL_DATABITS_6                 0x0002
262
#define SERIAL_DATABITS_7                 0x0004
263
#define SERIAL_DATABITS_8                 0x0008
264
#define SERIAL_DATABITS_16                0x0010
265
#define SERIAL_DATABITS_16X               0x0020
266
267
/* SERIAL_COMMPROP.SettableStopParity flags */
268
#define SERIAL_STOPBITS_10                0x0001
269
#define SERIAL_STOPBITS_15                0x0002
270
#define SERIAL_STOPBITS_20                0x0004
271
#define SERIAL_PARITY_NONE                0x0100
272
#define SERIAL_PARITY_ODD                 0x0200
273
#define SERIAL_PARITY_EVEN                0x0400
274
#define SERIAL_PARITY_MARK                0x0800
275
#define SERIAL_PARITY_SPACE               0x1000
276
277
typedef struct _SERIALPERF_STATS
278
{
279
    ULONG       ReceivedCount;
280
    ULONG       TransmittedCount;
281
    ULONG       FrameErrorCount;
282
    ULONG       SerialOverrunErrorCount;
283
    ULONG       BufferOverrunErrorCount;
284
    ULONG       ParityErrorCount;
285
} SERIALPERF_STATS, *PSERIALPERF_STATS;
286
287
typedef struct _SERIAL_TIMEOUTS
288
{
289
    ULONG       ReadIntervalTimeout;
290
    ULONG       ReadTotalTimeoutMultiplier;
291
    ULONG       ReadTotalTimeoutConstant;
292
    ULONG       WriteTotalTimeoutMultiplier;
293
    ULONG       WriteTotalTimeoutConstant;
294
} SERIAL_TIMEOUTS, *PSERIAL_TIMEOUTS;
295
296
/* IOCTL_SERIAL_(GET_WAIT_MASK, SET_WAIT_MASK, WAIT_ON_MASK) flags */
297
#define SERIAL_EV_RXCHAR                  0x0001
298
#define SERIAL_EV_RXFLAG                  0x0002
299
#define SERIAL_EV_TXEMPTY                 0x0004
300
#define SERIAL_EV_CTS                     0x0008
301
#define SERIAL_EV_DSR                     0x0010
302
#define SERIAL_EV_RLSD                    0x0020
303
#define SERIAL_EV_BREAK                   0x0040
304
#define SERIAL_EV_ERR                     0x0080
305
#define SERIAL_EV_RING                    0x0100
306
#define SERIAL_EV_PERR                    0x0200
307
#define SERIAL_EV_RX80FULL                0x0400
308
#define SERIAL_EV_EVENT1                  0x0800
309
#define SERIAL_EV_EVENT2                  0x1000
310
311
/* IOCTL_SERIAL_LSRMST_INSERT constants */
312
#define SERIAL_LSRMST_LSR_DATA            0x01
313
#define SERIAL_LSRMST_LSR_NODATA          0x02
314
#define SERIAL_LSRMST_MST                 0x03
315
#define SERIAL_LSRMST_ESCAPE              0x00
316
317
/* IOCTL_SERIAL_PURGE constants */
318
#define SERIAL_PURGE_TXABORT              0x00000001
319
#define SERIAL_PURGE_RXABORT              0x00000002
320
#define SERIAL_PURGE_TXCLEAR              0x00000004
321
#define SERIAL_PURGE_RXCLEAR              0x00000008
322
323
/* IOCTL_SERIAL_SET_FIFO_CONTROL constants */
324
#define SERIAL_IOC_FCR_FIFO_ENABLE        0x00000001
325
#define SERIAL_IOC_FCR_RCVR_RESET         0x00000002
326
#define SERIAL_IOC_FCR_XMIT_RESET         0x00000004
327
#define SERIAL_IOC_FCR_DMA_MODE           0x00000008
328
#define SERIAL_IOC_FCR_RES1               0x00000010
329
#define SERIAL_IOC_FCR_RES2               0x00000020
330
#define SERIAL_IOC_FCR_RCVR_TRIGGER_LSB   0x00000040
331
#define SERIAL_IOC_FCR_RCVR_TRIGGER_MSB   0x00000080
332
333
typedef struct _SERIAL_QUEUE_SIZE
334
{
335
    ULONG       InSize;
336
    ULONG       OutSize;
337
} SERIAL_QUEUE_SIZE, *PSERIAL_QUEUE_SIZE;
338
339
typedef struct _SERIAL_XOFF_COUNTER
340
{
341
    ULONG       Timeout;
342
    LONG        Counter;
343
    UCHAR       XoffChar;
344
} SERIAL_XOFF_COUNTER, *PSERIAL_XOFF_COUNTER;
345
346
typedef struct _SERIAL_BASIC_SETTINGS
347
{
348
    SERIAL_TIMEOUTS     Timeouts;
349
    SERIAL_HANDFLOW     HandFlow;
350
    ULONG       RxFifo;
351
    ULONG       TxFifo;
352
} SERIAL_BASIC_SETTINGS, *PSERIAL_BASIC_SETTINGS;
353
354
#define SERIAL_ERROR_BREAK                0x00000001
355
#define SERIAL_ERROR_FRAMING              0x00000002
356
#define SERIAL_ERROR_OVERRUN              0x00000004
357
#define SERIAL_ERROR_QUEUEOVERRUN         0x00000008
358
#define SERIAL_ERROR_PARITY               0x00000010
359
360
#define SERIAL_SP_UNSPECIFIED             0x00000000
361
#define SERIAL_SP_RS232                   0x00000001
362
#define SERIAL_SP_PARALLEL                0x00000002
363
#define SERIAL_SP_RS422                   0x00000003
364
#define SERIAL_SP_RS423                   0x00000004
365
#define SERIAL_SP_RS449                   0x00000005
366
#define SERIAL_SP_MODEM                   0X00000006
367
#define SERIAL_SP_FAX                     0x00000021
368
#define SERIAL_SP_SCANNER                 0x00000022
369
#define SERIAL_SP_BRIDGE                  0x00000100
370
#define SERIAL_SP_LAT                     0x00000101
371
#define SERIAL_SP_TELNET                  0x00000102
372
#define SERIAL_SP_X25                     0x00000103
373
#define SERIAL_SP_SERIALCOMM              0x00000001
374
375
#define SERIAL_TX_WAITING_FOR_CTS         0x00000001
376
#define SERIAL_TX_WAITING_FOR_DSR         0x00000002
377
#define SERIAL_TX_WAITING_FOR_DCD         0x00000004
378
#define SERIAL_TX_WAITING_FOR_XON         0x00000008
379
#define SERIAL_TX_WAITING_XOFF_SENT       0x00000010
380
#define SERIAL_TX_WAITING_ON_BREAK        0x00000020
381
#define SERIAL_RX_WAITING_FOR_DSR         0x00000040
382
383
#define SERIAL_DTR_STATE                  0x00000001
384
#define SERIAL_RTS_STATE                  0x00000002
385
#define SERIAL_CTS_STATE                  0x00000010
386
#define SERIAL_DSR_STATE                  0x00000020
387
#define SERIAL_RI_STATE                   0x00000040
388
#define SERIAL_DCD_STATE                  0x00000080
389
390
typedef struct _SERIALCONFIG
391
{
392
    ULONG       Size;
393
    USHORT      Version;
394
    ULONG       SubType;
395
    ULONG       ProvOffset;
396
    ULONG       ProviderSize;
397
    WCHAR       ProviderData[1];
398
} SERIALCONFIG,*PSERIALCONFIG;
399
400
#ifdef __cplusplus
401
}
402
#endif
403
404
#endif /* _NTDDSER_H_ */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/drivers/serial/rdp.c (+1622 lines)
Line 0    Link Here 
1
#include <linux/rdp.h>
2
#include <linux/tty_flip.h>
3
4
static struct rdp_tty * g_tty_driver = (struct rdp_tty *)NULL;
5
static DEFINE_MUTEX(g_tty_driver_mutex);
6
7
static struct mutex * p_tty_mutex = (struct mutex *)NULL;
8
static struct rdp_port g_ports[MAX_PORT];
9
static int g_port_count = 0;
10
11
static struct mutex g_write_mutex = {};
12
static struct mutex * p_write_mutex = (struct mutex *)NULL;
13
14
static struct rdp_cmd *			g_cmds[16];
15
static struct rdp_cmd *			g_pend[16];
16
static struct rdp_irq_entry *		g_read[16];
17
static struct rdp_write_entry *		g_write[16];
18
static completed_cmd_list_t *		g_compl[16];
19
static struct rdp_cb_entry *		g_cb[16];
20
static int g_initialized = 0;
21
22
static int rdp_receive(struct rdp_port *, int, int *, char *);
23
static void __cb_enq(struct rdp_cb_entry *);
24
static void cb_enq(struct rdp_cb_entry *);
25
static struct rdp_cb_entry * __cb_deq(struct rdp_cb_entry **);
26
static struct rdp_cb_entry * cb_deq(struct rdp_cb_entry **);
27
static void read_enq(struct rdp_irq_entry *);
28
static struct rdp_irq_entry * read_deq(struct rdp_irq_entry **);
29
static void write_enq(struct rdp_write_entry *);
30
static struct rdp_write_entry * write_deq(struct rdp_write_entry **);
31
static struct list_head * compl_enq(completed_cmd_list_t *);
32
static completed_cmd_list_t * __compl_deq(completed_cmd_list_t **);
33
static completed_cmd_list_t * compl_deq(completed_cmd_list_t **);
34
35
#define Q_NAME  "rdp_workq"
36
static void rdp_cmdw_handler(struct work_struct *);
37
static struct workqueue_struct * g_cmdq = (struct workqueue_struct *)NULL;
38
static DECLARE_WORK(g_cmdw, rdp_cmdw_handler);
39
40
#define COMPLQ_NAME  "rdp_compq"
41
static void rdp_complw_handler(struct work_struct *);
42
static struct workqueue_struct * g_complq = (struct workqueue_struct *)NULL;
43
//static DECLARE_DELAYED_WORK(g_complw, rdp_complw_handler);
44
static DECLARE_WORK(g_complw, rdp_complw_handler);
45
46
#define READQ_NAME  "rdp_readq"
47
static void rdp_readw_handler(struct work_struct *);
48
static struct workqueue_struct * g_readq = (struct workqueue_struct *)NULL;
49
static DECLARE_WORK(g_readw, rdp_readw_handler);
50
51
#define WRITEQ_NAME  "rdp_writeq"
52
static void rdp_writew_handler(struct work_struct *);
53
static struct workqueue_struct * g_writeq = (struct workqueue_struct *)NULL;
54
static DECLARE_WORK(g_writew, rdp_writew_handler);
55
56
static struct list_head * p_enq(struct rdp_cmd *);
57
58
static const char * cmdarray[] = CMD_TO_STRING_ARRAY_DEF;
59
60
static LIST_HEAD(rdp_completed_cmds);
61
static DEFINE_SPINLOCK(rdp_completed_cmds_lock);
62
63
static LIST_HEAD(rdp_read_list);
64
static DEFINE_SPINLOCK(rdp_read_lock);
65
static LIST_HEAD(rdp_write_list);
66
static DEFINE_SPINLOCK(rdp_write_lock);
67
68
static DEFINE_MUTEX(g_cb_mutex);
69
static struct mutex * p_cb_mutex = (struct mutex *)NULL;
70
71
72
/***
73
 ***	Netlink Connection ("cn") functions
74
 ***/
75
76
static struct rdp_family rdp_default_family = {};
77
78
static DEFINE_SPINLOCK(rdp_flock);
79
static DEFINE_SPINLOCK(rdp_cmd_lock);
80
static LIST_HEAD(rdp_families);
81
static LIST_HEAD(rdp_outbound_cmd_list);
82
static LIST_HEAD(rdp_pending_cmd_list);
83
84
#define CBQ_NAME  "rdp_cbq"
85
static void rdp_cn_callback_bh(CBARGS);
86
static LIST_HEAD(rdp_cb_list);
87
static DEFINE_SPINLOCK(rdp_cb_lock);
88
static void rdp_cbw_handler(struct work_struct *);
89
static struct workqueue_struct * g_cbq = (struct workqueue_struct *)NULL;
90
static DECLARE_WORK(g_cbw, rdp_cbw_handler);
91
92
93
static void rdp_cn_callback(CBARGS) {
94
      struct rdp_cb_entry * cb_entry = (struct rdp_cb_entry *)NULL;
95
      unsigned char * buf = (unsigned char *)NULL;
96
      unsigned char * sbuf = (unsigned char *)NULL;
97
      struct cn_msg * lmsg = (struct cn_msg *)NULL;
98
99
      if (imsg == NULL || g_initialized < 1) {
100
	goto end;
101
      }
102
      cb_entry = (struct rdp_cb_entry *)kzalloc((sizeof(struct rdp_cb_entry) + imsg->len + 1), GFP_ATOMIC);
103
      if (cb_entry == NULL) {
104
	goto end;
105
      }
106
      else {
107
	if (parms != NULL) {
108
	  memcpy(&(cb_entry->parms), parms, sizeof(struct netlink_skb_parms));
109
	}
110
	lmsg = &(cb_entry->imsg);
111
	buf = (unsigned char *)(lmsg + 1);
112
	sbuf = (unsigned char *)(imsg + 1);
113
//	memcpy(&(cb_entry->imsg), imsg, (sizeof(struct cn_msg) + imsg->len));
114
	memcpy(lmsg, imsg, sizeof(struct cn_msg));
115
	memcpy(buf, sbuf, imsg->len);
116
      }
117
118
      cb_enq(cb_entry);
119
      queue_work(g_cbq, &g_cbw);
120
121
  end:;
122
}
123
124
static void rdp_cbw_handler(struct work_struct * work) {
125
    struct rdp_cb_entry * cb = (struct rdp_cb_entry *)NULL;
126
127
    if (work == NULL || g_initialized < 1 || p_cb_mutex == NULL) {
128
      goto end;
129
    }
130
    mutex_lock(p_cb_mutex);
131
    cb_deq(&cb);
132
    if (cb != NULL) {
133
      rdp_cn_callback_bh(&(cb->imsg), &(cb->parms));
134
    }
135
    mutex_unlock(p_cb_mutex);
136
137
  end:;
138
}
139
140
static void rdp_cn_callback_bh(CBARGS) {
141
  unsigned long flags;
142
  int found = 0;
143
  int mlen = 0;
144
  int i = 0;
145
  int lcompleted = 0;
146
  uint8_t mtype = 0x00;
147
  int status = 0;
148
  struct cn_msg * msg = (struct cn_msg *)imsg;
149
  rdp_netlink_msg * m = (rdp_netlink_msg *)(msg + 1);
150
  struct device * gdev = (struct device *)NULL;
151
  if (msg == NULL) {
152
    DBGLOG(KERN_ERR "ERROR\t[%s()]: msg is a null pointer", __func__);
153
    goto end;
154
  }
155
  mutex_lock(&(g_tty_driver_mutex));
156
  if (g_tty_driver != NULL) {
157
    //smp_rmb();
158
    status = atomic_read(&(g_tty_driver->status));
159
  }
160
  else {
161
    status = RDP_STATUS_EXIT;
162
  }
163
  if (g_tty_driver == NULL || status != RDP_STATUS_NORMAL) {
164
  }
165
  else if (msg != NULL) {
166
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
167
    while (msg->len) {
168
      rdp_reg_num id;
169
      struct rdp_cmd * cmd = (struct rdp_cmd *)NULL;
170
      memcpy(&id, m->id.id, sizeof(rdp_reg_num));
171
      mtype |= m->type;
172
      mlen = m->len;
173
      if (msg->ack > 0 && mtype < 0x81) {
174
	spin_lock_irqsave(&rdp_cmd_lock, flags);
175
	for (i = 0; i < 16; i++) {
176
	  cmd = g_pend[i];
177
	  if (cmd != NULL) {
178
	    DBGLOG(KERN_INFO "INFO\t[%s()]: cmd->seqid = %d", __func__, cmd->seqid);
179
	    //smp_rmb();
180
	    lcompleted = atomic_read(&(cmd->completed));
181
	    if (cmd->seqid == msg->seq && lcompleted < 1) {
182
	      smp_mb__before_atomic_inc();
183
	      atomic_inc(&(cmd->completed));
184
	      found = 1;
185
	      g_pend[i] = NULL;
186
	      break;
187
	    }
188
	  }
189
	}
190
	spin_unlock_irqrestore(&rdp_cmd_lock, flags);
191
	if (likely(found > 0 && cmd != NULL)) {
192
	  completed_cmd_list_t * cmd_item = (completed_cmd_list_t *)NULL;
193
	  DBGLOG(KERN_INFO "INFO\t[%s()]: cmd found, queueing callback...", __func__);
194
	  if (cmd != NULL && cmd->aux != NULL) {
195
	    cmd_item = (completed_cmd_list_t *)(cmd->aux);
196
	    cmd->aux = (void *)NULL;
197
	  }
198
	  else {
199
	    cmd_item = (completed_cmd_list_t *)kzalloc(sizeof(completed_cmd_list_t), GFP_KERNEL);
200
	  }
201
	  cmd_item->cmd = cmd;
202
	  if (cmd != NULL && cmd->odata != NULL && cmd->olen > 0 && m->data != NULL && mlen > 0 && cmd->odata != m->data && cmd->olen == mlen) {
203
	    memcpy(cmd->odata, m->data, MINVAL(cmd->olen, mlen));
204
	    DBGLOG(KERN_INFO "INFO\t[%s()]: cmd->odata = %p; cmd->olen = %d; m->data = %p; m->len = %d", __func__, cmd->odata, cmd->olen, m->data, m->len);
205
	  }
206
	  compl_enq(cmd_item);
207
	  queue_work(g_complq, &g_complw);
208
	}
209
	else {
210
	  //DBGLOG(KERN_INFO "INFO\t[%s()]: cmd not found! (%d)", __func__, msg->seq);
211
	}
212
      }
213
      else if (mtype > 0 && m != NULL) {
214
	/* if an unsolicited cn packet is received, then it should be handled as a
215
	 * "virtual interrupt" received from the userspace daemon; so, queue up an
216
	 * ersatz irq handler:
217
	 */
218
	struct rdp_irq_data * irq_data = (struct rdp_irq_data *)(m->data);
219
	struct rdp_irq_entry * irq_entry = (struct rdp_irq_entry *)NULL;
220
	DBGLOG(KERN_INFO "INFO\t[%s()]: (IRQ)", __func__);
221
	mtype &= ~RDP_ASYNC;
222
	switch (mtype) {
223
	  case RDP_ADDPORT:
224
	    {
225
	      int i = 0;
226
	      DBGLOG(KERN_INFO "INFO\t[%s()]: calling tty_register_device()", __func__);
227
	      if (p_tty_mutex != NULL) {
228
		mutex_lock(p_tty_mutex);
229
	      }
230
	      i = g_port_count;
231
	      if (!(gdev = tty_register_device((struct tty_driver *)(g_tty_driver->driver), i, NULL))) {
232
		DBGLOG(KERN_ERR "ERROR\t[%s()]: tty_register_device() failed", __func__);
233
	      }
234
	      else if (g_ports[i].initialized > 0) {
235
		DBGLOG(KERN_ERR "ERROR\t[%s()]: port is already initialized", __func__);
236
	      }
237
	      else {
238
		DBGLOG(KERN_INFO "INFO\t[%s()]: tty_register_device() was successful", __func__);
239
		memset(&(g_ports[i]), 0, sizeof(struct rdp_port));
240
		mutex_init(&(g_ports[i].mut));
241
		mutex_lock(&(g_ports[i].mut));
242
		g_ports[i].initialized = 1;
243
		g_ports[i].g_ports_index = i;
244
		spin_lock_init(&(g_ports[i].cmd_lock));
245
		spin_lock_init(&(g_ports[i].status_lock));
246
		//smp_wmb();
247
		atomic_set(&(g_ports[i].open_count), 0);
248
		g_ports[i].rec.port = &(g_ports[i]);
249
		g_ports[i].rec.tty = g_ports[i].item;
250
		g_ports[i].rec.initialized = 1;
251
		g_ports[i].rec.owner = THIS_MODULE;
252
		if (g_tty_driver != NULL && g_tty_driver->driver != NULL && g_tty_driver->driver->name != NULL) {
253
		  scnprintf(g_ports[i].rec.name, RDP_MAXNAMELEN, "%s%d", g_tty_driver->driver->name, i);
254
		}
255
		spin_lock_init(&(g_ports[i].rec.lock));
256
		mutex_unlock(&(g_ports[i].mut));
257
		g_port_count++;
258
	      }
259
	      if (p_tty_mutex != NULL) {
260
		mutex_unlock(p_tty_mutex);
261
	      }
262
	    }
263
	    break;
264
	  case RDP_RXFULL:
265
	    {
266
		int idx = 0;
267
		int found = 0;
268
		const int nr = MAX_PORT;
269
		if (p_tty_mutex != NULL) {
270
		  mutex_lock(p_tty_mutex);
271
		}
272
		for (idx = 0; idx < nr; idx++) {
273
		  if (g_ports[idx].device_id == irq_data->device_id) {
274
		    found = 1;
275
		    break;
276
		  }
277
		}
278
		irq_entry = (struct rdp_irq_entry *)kzalloc(sizeof(struct rdp_irq_entry), GFP_KERNEL);
279
		if (irq_entry != NULL) {
280
		  irq_entry->data = irq_data;
281
		  if (found > 0) {
282
		    irq_entry->port = &(g_ports[idx]);
283
		  }
284
		  else {
285
		    irq_entry->port = &(g_ports[0]);
286
		  }
287
		  read_enq(irq_entry);
288
		  queue_work(g_readq, &g_readw);
289
		}
290
		if (p_tty_mutex != NULL) {
291
		  mutex_unlock(p_tty_mutex);
292
		}
293
	    }
294
	    break;
295
	  default:
296
	    {
297
	      DBGLOG(KERN_WARNING "WARNING\t[%s()]: INTERRUPT --> unrecognized opcode (\"0x%02x\")", __func__, mtype);
298
	    }
299
	    break;
300
	}
301
      }
302
      msg->len -= (sizeof(rdp_netlink_msg) + m->len);
303
      m = (rdp_netlink_msg *)(((u8 *)m) + m->len);
304
    }
305
  }
306
  mutex_unlock(&(g_tty_driver_mutex));
307
308
 end:;
309
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
310
}
311
312
313
static int rdp_netlink_send(struct rdp_record * dev, rdp_netlink_msg * msg, int seq, int memmode) {
314
	unsigned long flags;
315
	int rv = 0;
316
	char buf[512];
317
	struct cn_msg * m = (struct cn_msg *)buf;
318
	rdp_netlink_msg * w = (rdp_netlink_msg *)(m+1);
319
	DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
320
	if (dev == NULL) {
321
	  DBGLOG(KERN_WARNING "WARNING\t[%s()]: dev is a null pointer", __func__);
322
	  rv = -EINVAL;
323
	  goto end;
324
	}
325
	if (msg == NULL) {
326
	  DBGLOG(KERN_WARNING "WARNING\t[%s()]: msg is a null pointer", __func__);
327
	  rv = -EINVAL;
328
	  goto end;
329
	}
330
	memset(buf, 0, sizeof(buf));
331
	m->id.idx = CN_IDX_RDP;
332
	m->id.val = CN_VAL_RDP;
333
	spin_lock_irqsave(&(dev->lock), flags);
334
	m->seq = seq;
335
	spin_unlock_irqrestore(&(dev->lock), flags);
336
	rv = m->seq;
337
	m->len = sizeof(rdp_netlink_msg) + msg->len;
338
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call memcpy()...", __func__);
339
	memcpy(w, msg, m->len);
340
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cn_netlink_send()... {m->len = \"%d\"}", __func__, m->len);
341
	cn_netlink_send(m, 0, memmode);
342
  end:
343
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\").", __func__, rv);
344
	return rv;
345
}
346
347
static int rdp_init_netlink(void) {
348
	int rv = 0;
349
	struct cb_id rdp_id = {
350
		.idx		= CN_IDX_RDP,
351
		.val		= CN_VAL_RDP,
352
	};
353
	spin_lock_init(&(rdp_default_family.lock));
354
	DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
355
	rv = cn_add_callback(&rdp_id, "rdp", &rdp_cn_callback);
356
	DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
357
	return rv;
358
}
359
360
static void rdp_stop_netlink(void) {
361
	struct cb_id rdp_id = {
362
		.idx		= CN_IDX_RDP,
363
		.val		= CN_VAL_RDP,
364
	};
365
	DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
366
	cn_del_callback(&rdp_id);
367
	DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
368
}
369
370
int rdp_register_family(struct rdp_family * newf) {
371
	unsigned long flags;
372
	struct list_head * ent = (struct list_head *)NULL;
373
	struct list_head * n = (struct list_head *)NULL;
374
	struct rdp_family * f = (struct rdp_family *)NULL;
375
	int ret = 0;
376
377
	spin_lock_irqsave(&rdp_flock, flags);
378
	list_for_each_safe(ent, n, &rdp_families) {
379
	  f = list_entry(ent, struct rdp_family, family_entry);
380
	  if (f->fid == newf->fid) {
381
	    ret = -EEXIST;
382
	    break;
383
	  }
384
	}
385
386
	if (!ret) {
387
	  //smp_wmb();
388
	  atomic_set(&newf->refcnt, 0);
389
	  newf->need_exit = 0;
390
	  list_add_tail(&newf->family_entry, &rdp_families);
391
	}
392
	spin_unlock_irqrestore(&rdp_flock, flags);
393
394
	return ret;
395
}
396
397
void rdp_unregister_family(struct rdp_family * fent) {
398
	unsigned long flags;
399
	struct list_head * ent = (struct list_head *)NULL;
400
	struct list_head * n = (struct list_head *)NULL;
401
	struct rdp_family * f  = (struct rdp_family *)NULL;
402
	int refcnt = 0;
403
404
	spin_lock_irqsave(&rdp_flock, flags);
405
	list_for_each_safe(ent, n, &rdp_families) {
406
		f = list_entry(ent, struct rdp_family, family_entry);
407
		if (f->fid == fent->fid) {
408
			list_del(&fent->family_entry);
409
			break;
410
		}
411
	}
412
413
	fent->need_exit = 1;
414
415
	spin_unlock_irqrestore(&rdp_flock, flags);
416
417
	//smp_rmb();
418
	refcnt = atomic_read(&(fent->refcnt));
419
	while (refcnt) {
420
	  printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n", fent->fid, atomic_read(&fent->refcnt));
421
	  if (msleep_interruptible(1000)) {
422
	    flush_signals(current);
423
	  }
424
	  //smp_rmb();
425
	  refcnt = atomic_read(&(fent->refcnt));
426
	}
427
}
428
429
/*
430
 * Should be called under rdp_flock held.
431
 */
432
struct rdp_family * rdp_family_registered(u8 fid) {
433
	struct list_head * ent = (struct list_head *)NULL;
434
	struct list_head * n = (struct list_head *)NULL;
435
	struct rdp_family * f = (struct rdp_family *)NULL;
436
	int ret = 0;
437
	list_for_each_safe(ent, n, &rdp_families) {
438
		f = list_entry(ent, struct rdp_family, family_entry);
439
		if (f->fid == fid) {
440
			ret = 1;
441
			break;
442
		}
443
	}
444
	return (ret) ? f : NULL;
445
}
446
447
static void __rdp_family_put(struct rdp_family * f) {
448
	int tmp = 0;
449
	smp_mb__before_atomic_dec();
450
	tmp = atomic_dec_and_test(&f->refcnt);
451
	if (tmp) {
452
	  f->need_exit = 1;
453
	}
454
}
455
456
void rdp_family_put(struct rdp_family * f) {
457
	spin_lock(&rdp_flock);
458
	__rdp_family_put(f);
459
	spin_unlock(&rdp_flock);
460
}
461
462
static void __rdp_family_get(struct rdp_family *f) {
463
	smp_mb__before_atomic_inc();
464
	atomic_inc(&(f->refcnt));
465
}
466
467
void rdp_family_get(struct rdp_family *f) {
468
	spin_lock(&rdp_flock);
469
	__rdp_family_get(f);
470
	spin_unlock(&rdp_flock);
471
}
472
473
/*****/
474
/*****/
475
476
static int cmd_output(struct rdp_cmd * rcmd, int memmode) {
477
	unsigned long flags;
478
	int rv = 0;
479
	struct rdp_record * rec = (struct rdp_record *)NULL;
480
	struct rdp_family * f = (struct rdp_family *)NULL;
481
	unsigned char * cbuf = (unsigned char *)NULL;
482
	void * data = (void *)NULL;
483
	int len = 0;
484
	rdp_netlink_msg msg;
485
	unsigned char cmd = 0x00;
486
	struct rdp_port * port = (struct rdp_port *)NULL;
487
	struct tty_struct * tty = (struct tty_struct *)NULL;
488
	int ilen = 0;
489
	int olen = 0;
490
	void * idata = (void *)NULL;
491
	void * odata = (void *)NULL;
492
	uint32_t cmd_idx = 0x00000000;
493
494
	if (rcmd == NULL) {
495
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: rcmd is a NULL pointer", __func__);
496
	  rv = -EINVAL;
497
	  goto end;
498
	}
499
	else {
500
	  port = rcmd->port;
501
	  cmd = rcmd->cmd;
502
	  tty = rcmd->tty;
503
	  ilen = rcmd->ilen;
504
	  olen = rcmd->olen;
505
	  idata = rcmd->idata;
506
	  odata = rcmd->odata;
507
	  len = ilen;
508
	  data = idata;
509
	  cmd_idx = rcmd->cmd_idx;
510
	}
511
	if (ilen > 0 && idata == NULL) {
512
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: idata is a NULL pointer", __func__);
513
	  rv = -EINVAL;
514
	  goto end;
515
	}
516
	if (olen > 0 && odata == NULL) {
517
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: odata is a NULL pointer", __func__);
518
	  rv = -ENOMEM;
519
	  goto end;
520
	}
521
	if (cmd == RDP_PING || cmd > RDP_XCHAR) {
522
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: opcode not implemented (\"%8.8x\")", __func__, cmd);
523
	  rv = -EINVAL;
524
	  goto end;
525
	}
526
527
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", %d)", __func__, RDPCMD(cmd), cmd);
528
529
	rec = &(rcmd->port->rec);
530
531
	memset(&msg, 0, sizeof(rdp_netlink_msg));
532
	//smp_wmb();
533
	atomic_set(&(rec->refcnt), 0);
534
	INIT_COMPLETION(rec->released);
535
536
	spin_lock_irqsave(&rdp_flock, flags);
537
	f = &rdp_default_family;
538
	__rdp_family_get(f);
539
	rec->family = f;
540
	spin_unlock_irqrestore(&rdp_flock, flags);
541
542
	msg.type = cmd;
543
544
	if (len > 0 && data != NULL) {
545
	  msg.len = len + sizeof(uint32_t);
546
	  cbuf = (unsigned char *)kzalloc((sizeof(rdp_netlink_msg) + len), memmode);
547
	  if (cbuf == NULL) {
548
	    rv = -ENOMEM;
549
	    goto end;
550
	  }
551
	  else {
552
	    rdp_netlink_msg * pm = (rdp_netlink_msg *)cbuf;
553
	    uint32_t * pn = (uint32_t *)(pm+1);
554
	    unsigned char * pd = (unsigned char *)(pn+1);
555
	    memcpy(pm, &msg, sizeof(rdp_netlink_msg));
556
	    memcpy(pn, &cmd_idx, sizeof(uint32_t));
557
	    memcpy(pd, data, len);
558
	  }
559
	}
560
	else {
561
	  cbuf = (unsigned char *)kzalloc((sizeof(rdp_netlink_msg) + sizeof(uint32_t)), memmode);
562
	  if (cbuf == NULL) {
563
	    rv = -ENOMEM;
564
	    goto end;
565
	  }
566
	  else {
567
	    rdp_netlink_msg * pm = (rdp_netlink_msg *)cbuf;
568
	    uint32_t * pn = (uint32_t *)(pm+1);
569
	    memcpy(pm, &msg, sizeof(rdp_netlink_msg));
570
	    memcpy(pn, &cmd_idx, sizeof(uint32_t));
571
	  }
572
	}
573
	INIT_LIST_HEAD(&(rcmd->list));
574
	rcmd->seqid = rec->seq++;
575
	p_enq(rcmd);
576
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call rdp_netlink_send()...", __func__);
577
	rv = rdp_netlink_send(rec, (void *)cbuf, rcmd->seqid, memmode);
578
	DBGLOG(KERN_INFO "INFO\t[%s()]: (\" returned)", __func__);
579
580
	if (cbuf != NULL) {
581
	  kfree(cbuf);
582
	}
583
584
  end:
585
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\")", __func__, rv);
586
	return rv;
587
}
588
589
590
static struct list_head * __compl_enq(completed_cmd_list_t * cmd_item) {
591
  struct list_head * rv = (struct list_head *)NULL;
592
  int found = 0;
593
  int i = 0;
594
595
  if (cmd_item != NULL) {
596
    for (i = 0; i < 16; i++) {
597
      if (g_compl[i] == NULL) {
598
	found = 1;
599
	break;
600
      }
601
    }
602
    if (found) {
603
      g_compl[i] = cmd_item;
604
    }
605
    else {
606
      rv = NULL;
607
    }
608
  }
609
610
  return rv;
611
}
612
613
static struct list_head * compl_enq(completed_cmd_list_t * cmd_item) {
614
    unsigned long flags;
615
    struct list_head * rv = (struct list_head *)NULL;
616
617
    spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
618
    if (likely(cmd_item != NULL)) {
619
      rv = __compl_enq(cmd_item);
620
    }
621
    spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
622
623
    return rv;
624
}
625
626
static completed_cmd_list_t * __compl_deq(completed_cmd_list_t ** rcmd) {
627
  completed_cmd_list_t * rv = (completed_cmd_list_t *)NULL;
628
  int i = 0;
629
630
  for (i = 0; i < 16; i++) {
631
    if (g_compl[i] != NULL) {
632
      rv = g_compl[i];
633
      g_compl[i] = (completed_cmd_list_t *)NULL;
634
      break;
635
    }
636
  }
637
638
  /*
639
  if (list_empty(&rdp_completed_cmds)) {
640
    rv = (completed_cmd_list_t *)NULL;
641
  }
642
  else {
643
    rv = list_entry(rdp_completed_cmds.next, completed_cmd_list_t, list);
644
  }
645
  if (rv != NULL) {
646
    list_del_init(&(rv->list));
647
  }
648
  */
649
650
  if (rcmd != NULL) {
651
    *rcmd = rv;
652
  }
653
654
  return rv;
655
}
656
657
static completed_cmd_list_t * compl_deq(completed_cmd_list_t ** rcmd) {
658
  unsigned long flags;
659
  completed_cmd_list_t * rv = (completed_cmd_list_t *)NULL;
660
661
  spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
662
  rv = __compl_deq(rcmd);
663
  spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
664
665
  return rv;
666
}
667
668
669
static struct list_head * cmd_enq(struct rdp_cmd * rcmd) {
670
  unsigned long flags;
671
  int i = 0;
672
  int found = 0;
673
  struct list_head * rv = &rdp_outbound_cmd_list;
674
675
  if (rcmd != NULL) {
676
    spin_lock_irqsave(&rdp_cmd_lock, flags);
677
    for (i = 0; i < 16; i++) {
678
      if (g_cmds[i] == NULL) {
679
	found = 1;
680
	break;
681
      }
682
    }
683
    if (found) {
684
      g_cmds[i] = rcmd;
685
    }
686
    else {
687
      rv = NULL;
688
    }
689
    spin_unlock_irqrestore(&rdp_cmd_lock, flags);
690
  }
691
692
  return rv;
693
}
694
695
static struct rdp_cmd * cmd_deq(struct rdp_cmd ** rcmd) {
696
  unsigned long flags;
697
  int i = 0;
698
  struct rdp_cmd * rv = (struct rdp_cmd *)NULL;
699
700
  spin_lock_irqsave(&rdp_cmd_lock, flags);
701
  for (i = 0; i < 16; i++) {
702
    if (g_cmds[i] != NULL) {
703
      rv = g_cmds[i];
704
      g_cmds[i] = (struct rdp_cmd *)NULL;
705
      break;
706
    }
707
  }
708
  spin_unlock_irqrestore(&rdp_cmd_lock, flags);
709
710
  if (rcmd != NULL) {
711
    *rcmd = rv;
712
  }
713
714
  return rv;
715
}
716
717
static void read_enq(struct rdp_irq_entry * irq_entry) {
718
  unsigned long flags;
719
  int found = 0;
720
  int i = 0;
721
722
  if (irq_entry != NULL) {
723
    spin_lock_irqsave(&rdp_read_lock, flags);
724
    for (i = 0; i < 16; i++) {
725
      if (g_read[i] == NULL) {
726
	found = 1;
727
	break;
728
      }
729
    }
730
    if (found) {
731
      g_read[i] = irq_entry;
732
    }
733
    else {
734
      //rv = NULL;
735
    }
736
    spin_unlock_irqrestore(&rdp_read_lock, flags);
737
  }
738
739
740
  /*
741
  if (irq_entry != NULL) {
742
    INIT_LIST_HEAD(&(irq_entry->list));
743
    spin_lock_irqsave(&rdp_read_lock, flags);
744
    list_add_tail(&(irq_entry->list), &rdp_read_list);
745
    spin_unlock_irqrestore(&rdp_read_lock, flags);
746
  }
747
  */
748
}
749
750
static struct rdp_irq_entry * read_deq(struct rdp_irq_entry ** itm) {
751
  unsigned long flags;
752
  struct rdp_irq_entry * rv = (struct rdp_irq_entry *)NULL;
753
  int i = 0;
754
755
  spin_lock_irqsave(&rdp_read_lock, flags);
756
  for (i = 0; i < 16; i++) {
757
    if (g_read[i] != NULL) {
758
      rv = g_read[i];
759
      g_read[i] = (struct rdp_irq_entry *)NULL;
760
      break;
761
    }
762
  }
763
  spin_unlock_irqrestore(&rdp_read_lock, flags);
764
765
  /*
766
  spin_lock_irqsave(&rdp_read_lock, flags);
767
  rv = list_entry(rdp_read_list.next, struct rdp_irq_entry, list);
768
  if (rv != NULL) {
769
    list_del_init(&(rv->list));
770
  }
771
  spin_unlock_irqrestore(&rdp_read_lock, flags);
772
  */
773
774
  if (itm != NULL) {
775
    *itm = rv;
776
  }
777
778
  return rv;
779
}
780
781
static void write_enq(struct rdp_write_entry * write_entry) {
782
  unsigned long flags;
783
  int found = 0;
784
  int i = 0;
785
786
  if (write_entry != NULL) {
787
    spin_lock_irqsave(&rdp_write_lock, flags);
788
    for (i = 0; i < 16; i++) {
789
      if (g_write[i] == NULL) {
790
	found = 1;
791
	break;
792
      }
793
    }
794
    if (found) {
795
      g_write[i] = write_entry;
796
    }
797
    else {
798
      //rv = NULL;
799
    }
800
    spin_unlock_irqrestore(&rdp_write_lock, flags);
801
  }
802
803
  /*
804
    if (write_entry != NULL) {
805
      INIT_LIST_HEAD(&(write_entry->list));
806
      spin_lock_irqsave(&rdp_write_lock, flags);
807
      list_add_tail(&(write_entry->list), &rdp_write_list);
808
      spin_unlock_irqrestore(&rdp_write_lock, flags);
809
    }
810
  */
811
}
812
813
static struct rdp_write_entry * write_deq(struct rdp_write_entry ** itm) {
814
  unsigned long flags;
815
  struct rdp_write_entry * rv = (struct rdp_write_entry *)NULL;
816
  int i = 0;
817
818
  spin_lock_irqsave(&rdp_write_lock, flags);
819
  for (i = 0; i < 16; i++) {
820
    if (g_write[i] != NULL) {
821
      rv = g_write[i];
822
      g_write[i] = (struct rdp_write_entry *)NULL;
823
      break;
824
    }
825
  }
826
  spin_unlock_irqrestore(&rdp_write_lock, flags);
827
828
  /*
829
  spin_lock_irqsave(&rdp_write_lock, flags);
830
  rv = list_entry(rdp_write_list.next, struct rdp_write_entry, list);
831
  if (rv != NULL) {
832
    list_del_init(&(rv->list));
833
  }
834
  spin_unlock_irqrestore(&rdp_write_lock, flags);
835
  */
836
837
  if (itm != NULL) {
838
    *itm = rv;
839
  }
840
841
  return rv;
842
}
843
844
static void __cb_enq(struct rdp_cb_entry * cb_entry) {
845
  int found = 0;
846
  int i = 0;
847
848
  if (cb_entry != NULL) {
849
    for (i = 0; i < 16; i++) {
850
      if (g_cb[i] == NULL) {
851
	found = 1;
852
	break;
853
      }
854
    }
855
    if (found) {
856
      g_cb[i] = cb_entry;
857
    }
858
    else {
859
      //rv = NULL;
860
    }
861
  }
862
863
  /*
864
    if (cb_entry != NULL) {
865
      INIT_LIST_HEAD(&(cb_entry->list));
866
      spin_lock_irqsave(&rdp_cb_lock, flags);
867
      list_add_tail(&(cb_entry->list), &rdp_cb_list);
868
      spin_unlock_irqrestore(&rdp_cb_lock, flags);
869
    }
870
  */
871
}
872
873
static void cb_enq(struct rdp_cb_entry * cb_entry) {
874
    unsigned long flags;
875
876
    spin_lock_irqsave(&rdp_cb_lock, flags);
877
    __cb_enq(cb_entry);
878
    spin_unlock_irqrestore(&rdp_cb_lock, flags);
879
}
880
881
882
static struct rdp_cb_entry * __cb_deq(struct rdp_cb_entry ** itm) {
883
  struct rdp_cb_entry * rv = (struct rdp_cb_entry *)NULL;
884
  int i = 0;
885
886
  for (i = 0; i < 16; i++) {
887
    if (g_cb[i] != NULL) {
888
      rv = g_cb[i];
889
      g_cb[i] = (struct rdp_cb_entry *)NULL;
890
      break;
891
    }
892
  }
893
894
  /*
895
  rv = list_entry(rdp_cb_list.next, struct rdp_cb_entry, list);
896
  if (rv != NULL) {
897
    list_del_init(&(rv->list));
898
  }
899
  */
900
901
  if (itm != NULL) {
902
    *itm = rv;
903
  }
904
905
  return rv;
906
}
907
908
static struct rdp_cb_entry * cb_deq(struct rdp_cb_entry ** itm) {
909
    unsigned long flags;
910
    struct rdp_cb_entry * rv = (struct rdp_cb_entry *)NULL;
911
912
    spin_lock_irqsave(&rdp_cb_lock, flags);
913
    __cb_deq(&rv);
914
    if (itm != NULL) {
915
      *itm = rv;
916
    }
917
    spin_unlock_irqrestore(&rdp_cb_lock, flags);
918
919
    return rv;
920
}
921
922
923
static struct list_head * p_enq(struct rdp_cmd * rcmd) {
924
  unsigned long flags;
925
  int i = 0;
926
  int found = 0;
927
  struct list_head * rv = &rdp_outbound_cmd_list;
928
929
  if (rcmd != NULL) {
930
931
    spin_lock_irqsave(&rdp_cmd_lock, flags);
932
933
    for (i = 0; i < 16; i++) {
934
      if (g_pend[i] == NULL) {
935
	found = 1;
936
	break;
937
      }
938
    }
939
940
    if (found) {
941
      g_pend[i] = rcmd;
942
    }
943
    else {
944
      rv = NULL;
945
    }
946
947
    spin_unlock_irqrestore(&rdp_cmd_lock, flags);
948
  }
949
950
  return rv;
951
}
952
953
#ifdef DO_PDEQ
954
955
static struct rdp_cmd * p_deq(struct rdp_cmd ** rcmd) {
956
  unsigned long flags;
957
  int i = 0;
958
  struct rdp_cmd * rv = (struct rdp_cmd *)NULL;
959
960
  spin_lock_irqsave(&rdp_cmd_lock, flags);
961
  for (i = 0; i < 16; i++) {
962
    if (g_pend[i] != NULL) {
963
      rv = g_pend[i];
964
      g_pend[i] = (struct rdp_cmd *)NULL;
965
      break;
966
    }
967
  }
968
  spin_unlock_irqrestore(&rdp_cmd_lock, flags);
969
970
  if (rcmd != NULL) {
971
    *rcmd = rv;
972
  }
973
974
  return rv;
975
}
976
977
#endif
978
979
980
static int cmd_process_list(struct list_head * cmdlist) {
981
  int rv = 0;
982
  struct rdp_cmd * cmd = (struct rdp_cmd *)NULL;
983
984
  might_sleep();
985
986
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
987
988
  if (g_tty_driver != NULL) {
989
    do {
990
      cmd_deq(&cmd);
991
      if (cmd != NULL) {
992
	DBGLOG(KERN_INFO "INFO\t[%s()]: outputting RDP command", __func__);
993
//	cmd_output(cmd, GFP_ATOMIC);
994
	cmd_output(cmd, GFP_KERNEL);
995
      }
996
    } while (cmd != NULL);
997
  }
998
999
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1000
1001
  return rv;
1002
}
1003
1004
static struct rdp_cmd * cmd_send(struct rdp_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen, int memmode) {
1005
	int seqid = 0;
1006
	int cmd_idx = 0;
1007
	struct rdp_cmd * lcmd = (struct rdp_cmd *)NULL;
1008
1009
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", ilen = \"%d\", olen = \"%d\")", __func__, RDPCMD(cmd), ilen, olen);
1010
1011
	if (port == NULL) {
1012
	  goto end;
1013
	}
1014
1015
	lcmd = (struct rdp_cmd *)kzalloc(sizeof(struct rdp_cmd), memmode);
1016
1017
	if (lcmd == NULL) {
1018
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: lcmd == NULL", __func__);
1019
	  goto end;
1020
	}
1021
1022
	spin_lock_init(&(lcmd->lock));
1023
	lcmd->cmd = cmd;
1024
	lcmd->port = port;
1025
	lcmd->idata = idata;
1026
	lcmd->ilen = ilen;
1027
	lcmd->odata = odata;
1028
	lcmd->olen = olen;
1029
	lcmd->cmd_idx = cmd_idx;
1030
	lcmd->aux = (void *)kzalloc(sizeof(completed_cmd_list_t), memmode);
1031
	//smp_wmb();
1032
	atomic_set(&(lcmd->completed), 0);
1033
1034
	if (olen > 0 && lcmd->odata == NULL) {
1035
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: lcmd->odata == NULL", __func__);
1036
	  goto end;
1037
	}
1038
1039
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cmd_enq()...", __func__);
1040
	cmd_enq(lcmd);
1041
	DBGLOG(KERN_INFO "INFO\t[%s()]: cmd_enq() returned", __func__);
1042
1043
  end:;
1044
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (lcmd = \"%p\", seqid = \"%d\").", __func__, lcmd, seqid);
1045
	return lcmd;
1046
}
1047
1048
1049
static int __cmd_exec(struct rdp_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen, int memmode) {
1050
	unsigned long flags;
1051
	int rv = 0;
1052
	int seqid = 0;
1053
	int lcompleted = 0x00000000;
1054
	int cnt = 0;
1055
	const unsigned int max_timeout = 2000;	/* in jiffies: 1 jiffy = 0.004 sec	*/
1056
	struct rdp_cmd * lcmd = (struct rdp_cmd *)NULL;
1057
	DECLARE_COMPLETION_ONSTACK(tdone);
1058
	struct completion * ldone = (struct completion *)NULL;
1059
	//struct work_struct * lwork = (struct work_struct *)NULL;
1060
	//DECLARE_WORK(g_cmdw, rdp_cmdw_handler);
1061
	struct work_struct twork;
1062
	struct work_struct * lwork = &twork;
1063
1064
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", ilen = \"%d\", olen = \"%d\")", __func__, RDPCMD(cmd), ilen, olen);
1065
1066
	if (port == NULL) {
1067
	  rv = -EINVAL;
1068
	  goto end;
1069
	}
1070
1071
//	ldone = (struct completion *)kzalloc(sizeof(struct completion), memmode);
1072
	ldone = &tdone;
1073
	if (ldone == NULL) {
1074
	  rv = -ENOMEM;
1075
	  goto end;
1076
	}
1077
	else {
1078
//	  init_completion(ldone);
1079
	}
1080
1081
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cmd_send()...", __func__);
1082
	lcmd = cmd_send(port, cmd, idata, ilen, odata, olen, memmode);
1083
	DBGLOG(KERN_INFO "INFO\t[%s()]: cmd_send() returned", __func__);
1084
	if (lcmd == NULL) {
1085
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: \"lcmd\" is a NULL pointer", __func__);
1086
	  goto end;
1087
	}
1088
	lcmd->done = ldone;
1089
	DBGLOG(KERN_INFO "INFO\t[%s()]: queue_delayed_work() returned", __func__);
1090
1091
//	lwork = (struct work_struct *)kzalloc(sizeof(struct work_struct), memmode);
1092
	if (lwork == NULL) {
1093
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: \"lwork\" is a NULL pointer", __func__);
1094
	  goto end;
1095
	}
1096
//	INIT_WORK(lwork, rdp_cmdw_handler);
1097
	INIT_WORK_ON_STACK(lwork, rdp_cmdw_handler);
1098
1099
	do {
1100
	  DBGLOG(KERN_INFO "INFO\t[%s()]: waiting for completion... (%d)", __func__, cnt);
1101
//	  queue_work(g_cmdq, &g_cmdw);
1102
	  queue_work(g_cmdq, lwork);
1103
	  wait_for_completion_interruptible_timeout(ldone, max_timeout);
1104
	  flush_workqueue(g_cmdq);
1105
//	  spin_lock_irqsave(&(lcmd->lock), flags);
1106
//	  INIT_COMPLETION(*ldone);
1107
	  INIT_COMPLETION(tdone);
1108
	  //smp_rmb();
1109
	  lcompleted = atomic_read(&(lcmd->completed));
1110
//	  spin_unlock_irqrestore(&(lcmd->lock), flags);
1111
	  cnt++;
1112
	} while (!(lcompleted) && cnt < 5);
1113
	if (!lcompleted) {
1114
	  int i = 0;
1115
	  spin_lock_irqsave(&rdp_cmd_lock, flags);
1116
	  for (i = 0; i < 16; i++) {
1117
	    if (g_cmds[i] == lcmd) {
1118
	      g_cmds[i] = (struct rdp_cmd *)NULL;
1119
	      kfree(lcmd);
1120
	      lcmd = (struct rdp_cmd *)NULL;
1121
	    }
1122
	  }
1123
	  spin_unlock_irqrestore(&rdp_cmd_lock, flags);
1124
	}
1125
	DBGLOG(KERN_INFO "INFO\t[%s()]: (\" completed)", __func__);
1126
	if (lwork != NULL) {
1127
	  //kfree(lwork);
1128
	}
1129
1130
	if (lcmd != NULL && lcmd->olen > 0 && lcmd->odata != NULL && olen > 0 && odata != NULL && odata != lcmd->odata) {
1131
	  memcpy(odata, lcmd->odata, MINVAL(lcmd->olen,olen));
1132
	}
1133
	if (lcmd != NULL) {
1134
	  memset(lcmd, 0, sizeof(struct rdp_cmd));
1135
	  kfree(lcmd);
1136
	}
1137
1138
  end:;
1139
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\", seqid = \"%d\").", __func__, rv, seqid);
1140
	return rv;
1141
}
1142
1143
static int cmd_exec(struct rdp_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen) {
1144
    might_sleep();
1145
    return __cmd_exec(port, cmd, idata, ilen, odata, olen, GFP_KERNEL);
1146
}
1147
1148
1149
#define DO_RECEIVE	1
1150
#ifdef DO_RECEIVE
1151
1152
static int rdp_receive(struct rdp_port * port, int stat, int * ibuflen, char * buf) {
1153
	int rv = 1;
1154
	int buflen = 0;
1155
	unsigned char ch = 0;
1156
	struct tty_struct * tty = port->item;
1157
1158
	if (ibuflen != NULL) {
1159
	  buflen = *ibuflen;
1160
	}
1161
1162
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (stat = \"%d\", buflen = \"%d\")", __func__, stat, buflen);
1163
1164
	if (port == NULL || tty == NULL) {
1165
	  rv = -EINVAL;
1166
	  goto end;
1167
	}
1168
1169
	if (buflen == 1 && buf != NULL) {
1170
	  ch = buf[0];
1171
	  tty_insert_flip_char(tty, ch, 0);
1172
	}
1173
	else if (buflen > 1 && buf != NULL) {
1174
	  tty_insert_flip_string(tty, buf, buflen);
1175
	}
1176
1177
	if (buflen > 0) {
1178
	  tty_flip_buffer_push(tty);
1179
	}
1180
1181
1182
  end:
1183
	return rv;
1184
}
1185
1186
#endif
1187
1188
1189
static int supp_write(struct tty_struct * tty, const unsigned char * buffer, int count) {
1190
    unsigned long flags;
1191
    int rv = 0;
1192
    int cnt = 0;
1193
    int done = 0;
1194
    struct rdp_port * port = (struct rdp_port *)NULL;
1195
    struct work_struct * lwork = (struct work_struct *)NULL;
1196
    const unsigned int max_timeout = 2000;	/* in jiffies: 1 jiffy = 0.004 sec	*/
1197
1198
//    might_sleep();
1199
1200
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1201
1202
    if (tty != NULL && tty->index > -1 && tty->index < MAX_PORT) {
1203
      port = &(g_ports[tty->index]);
1204
    }
1205
    if (port == NULL) {
1206
      DBGLOG(KERN_ERR "ERROR\t[%s()]: tty->index out of range", __func__);
1207
      rv = -ENOMEM;
1208
      goto end;
1209
    }
1210
    else if (port->initialized < 1 || atomic_read(&(port->open_count)) < 1) {
1211
      DBGLOG(KERN_ERR "ERROR\t[%s()]: port is not open", __func__);
1212
      rv = -EACCES;
1213
      goto end;
1214
    }
1215
    else {
1216
      struct rdp_write_entry * write_entry = (struct rdp_write_entry *)NULL;
1217
1218
      if (p_write_mutex != NULL) {
1219
//	mutex_lock(p_write_mutex);
1220
      }
1221
1222
//      write_entry = (struct rdp_write_entry *)kzalloc(sizeof(struct rdp_write_entry), GFP_ATOMIC);
1223
      write_entry = (struct rdp_write_entry *)kzalloc(sizeof(struct rdp_write_entry), GFP_KERNEL);
1224
      spin_lock_init(&(write_entry->lock));
1225
//    spin_lock_irqsave(&(write_entry->lock), flags);
1226
      write_entry->port = port;
1227
      write_entry->len = count;
1228
      write_entry->data = (unsigned char *)buffer;
1229
      write_entry->rv = 0;
1230
      write_entry->completed = 0;
1231
      init_completion(&(write_entry->done));
1232
1233
      write_enq(write_entry);
1234
//    spin_unlock_irqrestore(&(write_entry->lock), flags);
1235
      //spin_lock_irqsave(&rdp_write_lock, flags);
1236
      //queue_work(g_writeq, &g_writew);
1237
      //spin_unlock_irqrestore(&rdp_write_lock, flags);
1238
	do {
1239
	  lwork = (struct work_struct *)kzalloc(sizeof(struct work_struct), GFP_KERNEL);
1240
	  INIT_WORK(lwork, rdp_writew_handler);
1241
	  DBGLOG(KERN_INFO "INFO\t[%s()]: waiting for completion... (%d)", __func__, cnt);
1242
	  queue_work(g_writeq, lwork);
1243
//	  wait_for_completion_interruptible_timeout(&(write_entry->done), max_timeout);
1244
//	  wait_for_completion_timeout(&(write_entry->done), max_timeout);
1245
//	  flush_workqueue(g_writeq);
1246
	  spin_lock_irqsave(&(write_entry->lock), flags);
1247
	  if (write_entry->completed > 0) {
1248
	    done = 1;
1249
	    kfree(lwork);
1250
	    lwork = (struct work_struct *)NULL;
1251
	  }
1252
	  else {
1253
	    done = 0;
1254
	    write_entry->canceled = 1;
1255
	  }
1256
//	  INIT_COMPLETION(write_entry->done);
1257
	  spin_unlock_irqrestore(&(write_entry->lock), flags);
1258
	  cnt++;
1259
	} while (!done && cnt < 3);
1260
1261
      if (p_write_mutex != NULL) {
1262
//	mutex_unlock(p_write_mutex);
1263
      }
1264
1265
      rv = count;
1266
    }
1267
1268
  end:;
1269
    return rv;
1270
}
1271
1272
static int supp_open(struct tty_struct * tty, struct file * file) {
1273
  int rv = 0;
1274
  uint32_t fd = 0;
1275
  int oc = 0;
1276
  struct rdp_port * port = (struct rdp_port *)NULL;
1277
1278
  might_sleep();
1279
1280
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1281
1282
  if (likely(tty != NULL && tty->index > -1 && tty->index < MAX_PORT)) {
1283
    port = &(g_ports[tty->index]);
1284
  }
1285
  if (unlikely(port == NULL)) {
1286
    DBGLOG(KERN_ERR "ERROR\t[%s()]: tty->index out of range", __func__);
1287
    rv = -ENOMEM;
1288
    goto end;
1289
  }
1290
  else {
1291
1292
    if (likely(port->initialized == 1 && port->item == NULL)) {
1293
      port->item = tty;
1294
      port->rec.tty = port->item;
1295
      port->rec.port = port;
1296
      port->fp = file;
1297
    }
1298
1299
    //smp_rmb();
1300
    oc = atomic_read(&(port->open_count));
1301
    cmd_exec(port, RDP_OPEN, NULL, 0, &fd, sizeof(fd));
1302
    DBGLOG(KERN_INFO "INFO\t[%s()]: fd = %d", __func__, fd);
1303
    rv = fd;
1304
    if (oc == 0) {
1305
      cmd_exec(port, RDP_START, NULL, 0, NULL, 0);
1306
    }
1307
    smp_mb__before_atomic_inc();
1308
    atomic_inc(&(port->open_count));
1309
1310
  }
1311
1312
  end:;
1313
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1314
  return rv;
1315
}
1316
1317
static void supp_close(struct tty_struct * tty, struct file * file) {
1318
    int oc = 0;
1319
    struct rdp_port * port = (struct rdp_port *)NULL;
1320
1321
    might_sleep();
1322
1323
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1324
1325
    if (likely(tty != NULL && tty->index > -1 && tty->index < MAX_PORT && g_ports[tty->index].initialized > 0)) {
1326
      port = &(g_ports[tty->index]);
1327
    }
1328
    if (unlikely(port == NULL || port->item == NULL || port->initialized < 1)) {
1329
      DBGLOG(KERN_ERR "ERROR\t[%s()]: port or port->item is NULL or not initialized", __func__);
1330
    }
1331
    else {
1332
      //smp_rmb();
1333
      oc = atomic_read(&(port->open_count));
1334
      if (oc == 1) {
1335
	cmd_exec(port, RDP_STOP, NULL, 0, NULL, 0);
1336
      }
1337
      cmd_exec(port, RDP_CLOSE, NULL, 0, NULL, 0);
1338
      smp_mb__before_atomic_dec();
1339
      atomic_dec(&(port->open_count));
1340
    }
1341
}
1342
1343
int __init rdp_ops_setup(struct tty_operations * ops) {
1344
    int rv = 0;
1345
1346
    if (ops == NULL) {
1347
      rv = -EINVAL;
1348
      goto exit;
1349
    }
1350
    ops->open = supp_open;
1351
    ops->close = supp_close;
1352
    ops->write = supp_write;
1353
1354
  exit:;
1355
    return rv;
1356
}
1357
1358
int __init rdp_init(struct tty_driver * drv, struct mutex * tty_mutex) {
1359
  int rv = 0;
1360
1361
  might_sleep();
1362
1363
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1364
1365
  //mutex_lock(&(g_tty_driver_mutex));
1366
1367
  if (p_tty_mutex == NULL) {
1368
    p_tty_mutex = tty_mutex;
1369
  }
1370
  p_write_mutex = &g_write_mutex;
1371
  memset(p_write_mutex, 0x00, sizeof(struct mutex));
1372
  //mutex_init(p_write_mutex);
1373
1374
  memset(g_ports, 0, sizeof(g_ports));
1375
  memset(g_cmds, 0, sizeof(g_cmds));
1376
  memset(g_pend, 0, sizeof(g_pend));
1377
  memset(g_read, 0, sizeof(g_read));
1378
  memset(g_write, 0, sizeof(g_write));
1379
  memset(g_compl, 0, sizeof(g_compl));
1380
  memset(g_cb, 0, sizeof(g_cb));
1381
1382
  g_tty_driver = (struct rdp_tty *)kzalloc(sizeof(struct rdp_tty), GFP_KERNEL);
1383
  //mutex_init(&(g_tty_driver_mutex));
1384
  //mutex_lock(&(g_tty_driver_mutex));
1385
  g_tty_driver->driver = drv;
1386
  if (p_cb_mutex == NULL) {
1387
    memset(&g_cb_mutex, 0x00, sizeof(struct mutex));
1388
    p_cb_mutex = &g_cb_mutex;
1389
  }
1390
  //mutex_init(p_cb_mutex);
1391
  //mutex_lock(p_cb_mutex);
1392
  //smp_wmb();
1393
  atomic_set(&(g_tty_driver->status), RDP_STATUS_LOADING);
1394
  g_cbq = create_singlethread_workqueue(CBQ_NAME);
1395
  g_cmdq = create_singlethread_workqueue(Q_NAME);
1396
  g_complq = create_singlethread_workqueue(COMPLQ_NAME);
1397
  g_readq = create_singlethread_workqueue(READQ_NAME);
1398
  g_writeq = create_singlethread_workqueue(WRITEQ_NAME);
1399
  //smp_wmb();
1400
  atomic_set(&(g_tty_driver->status), RDP_STATUS_NORMAL);
1401
  g_initialized = 1;
1402
  //mutex_unlock(p_cb_mutex);
1403
  rdp_init_netlink();
1404
  //mutex_unlock(&(g_tty_driver_mutex));
1405
1406
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1407
  return rv;
1408
}
1409
1410
void __exit rdp_exit(struct tty_driver * tty) {
1411
  struct rdp_tty * l_tty_driver = (struct rdp_tty *)NULL;
1412
  might_sleep();
1413
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1414
  //mutex_lock(&(g_tty_driver_mutex));
1415
  if (g_tty_driver != NULL && g_initialized > 0) {
1416
    l_tty_driver = g_tty_driver;
1417
    //smp_wmb();
1418
    atomic_set(&(g_tty_driver->status), RDP_STATUS_EXIT);
1419
  }
1420
  g_initialized = 0;
1421
  //mutex_unlock(&(g_tty_driver_mutex));
1422
  destroy_workqueue(g_cbq);
1423
  destroy_workqueue(g_writeq);
1424
  destroy_workqueue(g_readq);
1425
  destroy_workqueue(g_cmdq);
1426
  destroy_workqueue(g_complq);
1427
  //mutex_lock(&(g_tty_driver_mutex));
1428
  if (g_tty_driver != NULL) {
1429
    if (g_tty_driver->driver != NULL) {
1430
      int i = 0;
1431
      for (i = 0; i < MAX_PORT; i++) {
1432
	if (g_ports[i].initialized) {
1433
	  //mutex_lock(&(g_ports[i].mut));
1434
	  tty_unregister_device(g_tty_driver->driver, i);
1435
	  g_ports[i].initialized = 0;
1436
	  //mutex_unlock(&(g_ports[i].mut));
1437
	}
1438
      }
1439
    }
1440
    g_tty_driver->driver = (struct tty_driver *)NULL;
1441
    g_tty_driver = (struct rdp_tty *)NULL;
1442
    //mutex_unlock(&(l_tty_driver->mut));
1443
    memset(g_tty_driver, 0, sizeof(struct rdp_tty));
1444
    kfree(l_tty_driver);
1445
    l_tty_driver = (struct rdp_tty *)NULL;
1446
  }
1447
  rdp_stop_netlink();
1448
  p_cb_mutex = (struct mutex *)NULL;
1449
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1450
}
1451
1452
static void rdp_cmdw_handler(struct work_struct * work) {
1453
  unsigned long status = RDP_STATUS_ERROR;
1454
  //mutex_lock(&(g_tty_driver_mutex));
1455
  if (g_tty_driver != NULL) {
1456
    //smp_rmb();
1457
    status = atomic_read(&(g_tty_driver->status));
1458
    if (g_tty_driver != NULL && status == RDP_STATUS_NORMAL) {
1459
      cmd_process_list(&rdp_outbound_cmd_list);
1460
    }
1461
  }
1462
  //mutex_unlock(&(g_tty_driver_mutex));
1463
}
1464
1465
/*
1466
static void rdp_complw_handler_old(struct work_struct * work) {
1467
    unsigned long flags;
1468
    completed_cmd_list_t * cmd_item = (completed_cmd_list_t *)NULL;
1469
    int lcompleted = 0;
1470
    struct list_head * ent = (struct list_head *)NULL;
1471
    struct list_head * n = (struct list_head *)NULL;
1472
1473
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1474
1475
    spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
1476
    list_for_each_safe(ent, n, &rdp_completed_cmds) {
1477
      if (list_empty(&rdp_completed_cmds)) {
1478
        cmd_item = NULL;
1479
      }
1480
      else {
1481
        cmd_item = list_entry(ent, completed_cmd_list_t, list);
1482
      }
1483
      if (cmd_item != NULL && cmd_item->cmd != NULL) {
1484
        struct rdp_cmd * cmd = cmd_item->cmd;
1485
        //smp_rmb();
1486
        lcompleted = atomic_read(&(cmd->completed));
1487
        if (lcompleted == 1) {
1488
	  smp_mb__before_atomic_inc();
1489
	  atomic_inc(&(cmd->completed));
1490
	  DBGLOG(KERN_INFO "INFO\t[%s()]: completing a cmd...", __func__);
1491
//	  complete_all(cmd->done);
1492
	  complete(cmd->done);
1493
	  DBGLOG(KERN_INFO "INFO\t[%s()]: (completed)", __func__);
1494
        }
1495
        list_del_init(&(cmd_item->list));
1496
      }
1497
    }
1498
    spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
1499
1500
    DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1501
}
1502
*/
1503
1504
static void rdp_complw_handler(struct work_struct * work) {
1505
    unsigned long flags;
1506
    completed_cmd_list_t * cmd_item = (completed_cmd_list_t *)NULL;
1507
    int lcompleted = 0;
1508
    int i = 0;
1509
1510
    DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
1511
1512
    spin_lock_irqsave(&rdp_completed_cmds_lock, flags);
1513
    for (i = 0; i < 16; i++) {
1514
      cmd_item = g_compl[i];
1515
      if (cmd_item != NULL && cmd_item->cmd != NULL) {
1516
	struct rdp_cmd * cmd = (struct rdp_cmd *)NULL;
1517
	cmd = cmd_item->cmd;
1518
	//spin_lock(&(cmd->lock));
1519
	//smp_rmb();
1520
	lcompleted = atomic_read(&(cmd->completed));
1521
	if (lcompleted >= 1) {
1522
	  smp_mb__before_atomic_inc();
1523
	  atomic_inc(&(cmd->completed));
1524
	  if (cmd->done != NULL) {
1525
	    DBGLOG(KERN_INFO "INFO\t[%s()]: completing a cmd...", __func__);
1526
	    complete_all(cmd->done);
1527
	    DBGLOG(KERN_INFO "INFO\t[%s()]: (completed)", __func__);
1528
	  }
1529
	  g_compl[i] = (completed_cmd_list_t *)NULL;
1530
	}
1531
	//spin_unlock(&(cmd->lock));
1532
      }
1533
    }
1534
    spin_unlock_irqrestore(&rdp_completed_cmds_lock, flags);
1535
1536
    DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
1537
}
1538
1539
static void rdp_readw_handler(struct work_struct * work) {
1540
  struct rdp_irq_entry * irq_entry = (struct rdp_irq_entry *)NULL;
1541
  struct rdp_irq_data * irq_data = (struct rdp_irq_data *)NULL;
1542
  struct tty_struct * tty = (struct tty_struct *)NULL;
1543
  unsigned char mut_locked = 0;
1544
1545
  might_sleep();
1546
1547
  if (p_tty_mutex != NULL) {
1548
    //mutex_lock(p_tty_mutex);
1549
    mut_locked = 1;
1550
  }
1551
  //mutex_lock(&(g_tty_driver_mutex));
1552
  if (g_tty_driver != NULL && mut_locked > 0) {
1553
    if (g_tty_driver->driver != NULL) {
1554
      read_deq(&irq_entry);
1555
      if (irq_entry != NULL) {
1556
	irq_data = irq_entry->data;
1557
	if (irq_entry->port != NULL && irq_data != NULL && irq_data->rx_len > 0 && irq_data->rx_buf != NULL && irq_entry->port->item != NULL && irq_entry->port->item->driver_data != NULL) {
1558
	  struct rdptty_serial * rdp = (struct rdptty_serial *)NULL;
1559
	  tty = irq_entry->port->item;
1560
	  rdp = (struct rdptty_serial *)(tty->driver_data);
1561
	  if (rdp != NULL) {
1562
	    //mutex_lock(&(rdp->mut));
1563
	    rdp_receive(irq_entry->port, 0, &(irq_data->rx_len), irq_data->rx_buf);
1564
	    //mutex_unlock(&(rdp->mut));
1565
	  }
1566
	}
1567
      }
1568
    }
1569
  }
1570
  mutex_unlock(&(g_tty_driver_mutex));
1571
  if (p_tty_mutex != NULL && mut_locked > 0) {
1572
    mutex_unlock(p_tty_mutex);
1573
  }
1574
}
1575
1576
static void rdp_writew_handler(struct work_struct * work) {
1577
  unsigned long flags;
1578
  struct rdp_port * port = (struct rdp_port *)NULL;
1579
  struct rdp_write_entry * write_entry = (struct rdp_write_entry *)NULL;
1580
  unsigned char * buf = (unsigned char *)NULL;
1581
  int len = 0;
1582
  unsigned char mut_locked = 0;
1583
  int rv = 0;
1584
1585
  might_sleep();
1586
1587
  if (p_tty_mutex != NULL) {
1588
    mutex_lock(p_tty_mutex);
1589
    mut_locked = 1;
1590
  }
1591
  mutex_lock(&(g_tty_driver_mutex));
1592
  if (g_tty_driver != NULL && mut_locked > 0) {
1593
    if (g_tty_driver->driver != NULL) {
1594
      write_deq(&write_entry);
1595
      if (write_entry != NULL) {
1596
	spin_lock_irqsave(&(write_entry->lock), flags);
1597
      }
1598
      if (write_entry != NULL && write_entry->data != NULL && write_entry->len > 0 && write_entry->canceled != 1 && write_entry->completed < 1) {
1599
	port = write_entry->port;
1600
	len = write_entry->len;
1601
	buf = write_entry->data;
1602
	if (port != NULL && buf != NULL && len > 0) {
1603
	  DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cmd_exec(RDP_WRITE)...", __func__);
1604
	  spin_unlock_irqrestore(&(write_entry->lock), flags);
1605
	  cmd_exec(port, RDP_WRITE, buf, len, &rv, sizeof(int));
1606
	  spin_lock_irqsave(&(write_entry->lock), flags);
1607
	  DBGLOG(KERN_INFO "INFO\t[%s()]: rv = %d", __func__, rv);
1608
	}
1609
	write_entry->rv = rv;
1610
	write_entry->completed = 1;
1611
	complete_all(&(write_entry->done));
1612
      }
1613
      if (write_entry != NULL) {
1614
	spin_unlock_irqrestore(&(write_entry->lock), flags);
1615
      }
1616
    }
1617
  }
1618
  mutex_unlock(&(g_tty_driver_mutex));
1619
  if (p_tty_mutex != NULL && mut_locked > 0) {
1620
    mutex_unlock(p_tty_mutex);
1621
  }
1622
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/drivers/serial/rdptty.c (+827 lines)
Line 0    Link Here 
1
/*
2
 * RDP TTY driver
3
 *
4
 * Copyright (C) 2002-2010 Ryan Rafferty (ryanaxp@gmail.com)
5
 *
6
 *      This program is free software; you can redistribute it and/or modify
7
 *      it under the terms of the GNU General Public License as published by
8
 *      the Free Software Foundation, version 2 of the License.
9
 *
10
 */
11
12
#include <linux/kernel.h>
13
#include <linux/errno.h>
14
#include <linux/init.h>
15
#include <linux/module.h>
16
#include <linux/version.h>
17
#include <linux/slab.h>
18
#include <linux/wait.h>
19
#include <linux/tty.h>
20
#include <linux/tty_driver.h>
21
#include <linux/tty_flip.h>
22
#include <linux/serial.h>
23
#include <linux/sched.h>
24
#include <linux/rdp.h>
25
26
#include <asm/uaccess.h>
27
28
#include "ntddser.h"
29
30
#define DRIVER_VERSION "v0.9"
31
#define DRIVER_AUTHOR "Ryan Rafferty <ryanaxp@gmail.com>"
32
#define DRIVER_DESC "RDP TTY driver"
33
#define DRIVER_LICENSE "GPL"
34
35
/* Module information */
36
MODULE_AUTHOR( DRIVER_AUTHOR );
37
MODULE_DESCRIPTION( DRIVER_DESC );
38
MODULE_LICENSE( DRIVER_LICENSE );
39
40
41
extern int __init rdp_ops_setup(struct tty_operations *);
42
extern int __init rdp_init(struct tty_driver *, struct mutex *);
43
extern void __exit rdp_exit(struct tty_driver *);
44
45
#define C_RDP_TTY_MAJOR		240     /* experimental range */
46
#define C_RDP_TTY_MINORS		4       /* only have 4 devices */
47
#define C_RDP_TTY_NAME		"rdptty"
48
#define C_RDP_TTY_DEV		"ttyRDP"
49
50
const unsigned int	RDP_TTY_MAJOR	= 240;
51
const unsigned int	RDP_TTY_MINORS	= 4;
52
const char		RDP_TTY_NAME[]	= "rdptty";
53
const char		RDP_TTY_DEV[]	= "ttyRDP";
54
55
static int major = C_RDP_TTY_MAJOR;
56
static int minor = C_RDP_TTY_MINORS;
57
static char * name = (char *)NULL;
58
static char * dev = (char *)NULL;
59
60
module_param(major, int, 0644);
61
MODULE_PARM_DESC(major, "TTY major device number (default: 240)");
62
module_param(minor, int, 0644);
63
MODULE_PARM_DESC(minor, "TTY minor device number (default: 4)");
64
module_param(name, charp, 0644);
65
MODULE_PARM_DESC(name, "TTY device identifier (default: \"rdptty\")");
66
module_param(dev, charp, 0644);
67
MODULE_PARM_DESC(dev, "TTY device node filename (default: \"ttyRDP\")");
68
69
extern struct rdp_port g_ports[MAX_PORT];
70
71
static struct tty_operations rdp_tty_ops;
72
73
static DEFINE_MUTEX(g_tty_mutex);
74
static struct mutex * p_tty_mutex = (struct mutex *)NULL;
75
76
struct rdp_port * rdptty_table[C_RDP_TTY_MINORS];		/* initially all NULL */
77
78
static int rdptty_open(struct tty_struct * tty, struct file * file) {
79
	struct rdp_port * rdp = (struct rdp_port *)NULL;
80
	int index = 0;
81
	int rv = 0;
82
83
	might_sleep();
84
85
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
86
87
	if (p_tty_mutex != NULL) {
88
	  mutex_lock(p_tty_mutex);
89
	}
90
	if (tty == NULL) {
91
	  rv = -ENODEV;
92
	  goto exit;
93
	}
94
95
	/* initialize the pointer in case something fails */
96
	tty->driver_data = NULL;
97
98
	/* get the serial object associated with this tty pointer */
99
	index = tty->index;
100
	rdp = rdptty_table[index];
101
	if (rdp == NULL) {
102
	  /* first time accessing this device, let's create it */
103
	  rdp = &(g_ports[index]);
104
	  if (rdp == NULL) {
105
	    rv = -ENOMEM;
106
	    goto exit;
107
	  }
108
	  else {
109
	    mutex_init(&(rdp->mut));
110
	    mutex_lock(&(rdp->mut));
111
	    atomic_set(&(rdp->open_count), 0);
112
	    rdptty_table[index] = rdp;
113
	  }
114
	}
115
	else {
116
	  mutex_lock(&(rdp->mut));
117
	}
118
119
	if (rdp_tty_ops.open) {
120
	  rv = (rdp_tty_ops.open(tty, file) > 0) ? 0 : -EIO;
121
	}
122
123
	/* save our structure within the tty structure */
124
	tty->driver_data = rdp;
125
	rdp->tty = tty;
126
	smp_mb__before_atomic_inc();
127
	atomic_inc(&(rdp->open_count));
128
	if (atomic_read(&(rdp->open_count)) == 1) {
129
	  /* this is the first time this port is opened */
130
	  /* do any hardware initialization needed here */
131
	}
132
133
	mutex_unlock(&(rdp->mut));
134
135
    exit:;
136
	if (p_tty_mutex != NULL) {
137
	  mutex_unlock(p_tty_mutex);
138
	}
139
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
140
	return rv;
141
}
142
143
static void do_close(struct rdp_port * rdp) {
144
    if (rdp != NULL) {
145
	if (atomic_read(&(rdp->open_count)) > 0) {
146
	  smp_mb__before_atomic_dec();
147
	  atomic_dec(&(rdp->open_count));
148
	  if (atomic_read(&(rdp->open_count)) <= 0) {
149
	    /* The port is being closed by the last user. */
150
	    /* Do any hardware specific stuff here */
151
	  }
152
	}
153
    }
154
}
155
156
static void rdptty_close(struct tty_struct * tty, struct file * file) {
157
	struct rdp_port * rdp = (struct rdp_port *)NULL;
158
159
	might_sleep();
160
161
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
162
163
	if (p_tty_mutex != NULL) {
164
	  mutex_lock(p_tty_mutex);
165
	}
166
	if (tty != NULL) {
167
	  rdp = tty->driver_data;
168
	}
169
	if (rdp) {
170
	  mutex_lock(&(rdp->mut));
171
	  do_close(rdp);
172
	  if (rdp_tty_ops.close) {
173
	    rdp_tty_ops.close(tty, file);
174
	  }
175
	  mutex_unlock(&(rdp->mut));
176
	}
177
	if (p_tty_mutex != NULL) {
178
	  mutex_unlock(p_tty_mutex);
179
	}
180
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
181
}
182
183
static int rdptty_putchar(struct tty_struct * tty, const unsigned char ch) {
184
	struct rdp_port * rdp = (struct rdp_port *)NULL;
185
	int retval = -EINVAL;
186
	char cbuf[2] = {0x00, 0x00};
187
188
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
189
190
	if (tty != NULL && tty->driver_data != NULL) {
191
	  rdp = (struct rdp_port *)(tty->driver_data);
192
	}
193
194
	if (rdp == NULL) {
195
	  retval = -ENODEV;
196
	}
197
	else {
198
199
	  if (atomic_read(&(rdp->open_count)) < 1) {
200
	    /* port was not opened */
201
	    goto exit;
202
	  }
203
204
	  if (rdp_tty_ops.write) {
205
	    cbuf[0] = ch;
206
	    retval = rdp_tty_ops.write(tty, cbuf, 1);
207
	    printk("INFO\t[%s()]: retval = %d", __FUNCTION__, retval);
208
	  }
209
210
	  /* fake sending the data out a hardware port by
211
	   * writing it to the kernel debug log.
212
	   */
213
	  printk(KERN_DEBUG "%s - ", __FUNCTION__);
214
	  printk("%02x\t(\"%c\")\n", ch, ch);
215
216
	  exit:;
217
218
	}
219
220
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
221
	return retval;
222
}
223
224
static int rdptty_write(struct tty_struct * tty, const unsigned char * buffer, int count) {
225
	struct rdp_port * rdp = (struct rdp_port *)NULL;
226
	int i = 0;
227
	int retval = -EINVAL;
228
229
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
230
231
	if (tty != NULL && tty->driver_data != NULL) {
232
	  rdp = (struct rdp_port *)(tty->driver_data);
233
	}
234
235
	if (rdp == NULL) {
236
	  retval = -ENODEV;
237
	}
238
	else {
239
240
	  if (atomic_read(&(rdp->open_count)) < 1) {
241
	    /* port was not opened */
242
	    goto exit;
243
	  }
244
245
	  if (rdp_tty_ops.write) {
246
	    retval = rdp_tty_ops.write(tty, buffer, count);
247
	    printk("INFO\t[%s()]: retval = %d", __FUNCTION__, retval);
248
	  }
249
250
	  /* fake sending the data out a hardware port by
251
	   * writing it to the kernel debug log.
252
	   */
253
	  printk(KERN_DEBUG "%s - ", __FUNCTION__);
254
	  for (i = 0; i < count; ++i) {
255
	    printk("%02x ", buffer[i]);
256
	  }
257
	  printk("\t(\"");
258
	  for (i = 0; i < count; ++i) {
259
	    printk("%c", buffer[i]);
260
	  }
261
	  printk("\")\n");
262
263
	  exit:;
264
	}
265
266
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
267
	return retval;
268
}
269
270
static int rdptty_write_room(struct tty_struct * tty) {
271
	struct rdp_port * rdp = (struct rdp_port *)NULL;
272
	int room = -EINVAL;
273
274
	might_sleep();
275
276
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
277
278
	if (p_tty_mutex != NULL) {
279
	  mutex_lock(p_tty_mutex);
280
	}
281
282
	if (likely(tty != NULL)) {
283
	  rdp = (struct rdp_port *)(tty->driver_data);
284
	}
285
	if (unlikely(rdp == NULL)) {
286
	  room = -ENODEV;
287
	}
288
	else {
289
	  mutex_lock(&(rdp->mut));
290
	  if (atomic_read(&(rdp->open_count)) > 0) {
291
	    /* calculate how much room is left in the device */
292
	    //room = 255;
293
	    room = 1;
294
	  }
295
	  mutex_unlock(&(rdp->mut));
296
	}
297
	if (p_tty_mutex != NULL) {
298
	  mutex_unlock(p_tty_mutex);
299
	}
300
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
301
	return room;
302
}
303
304
#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
305
306
static void rdptty_set_termios(struct tty_struct * tty, struct ktermios * old_termios) {
307
	unsigned int cflag = 0;
308
309
	might_sleep();
310
311
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
312
313
	if (p_tty_mutex != NULL) {
314
	  mutex_lock(p_tty_mutex);
315
	}
316
	if (tty != NULL && tty->termios != NULL) {
317
	  cflag = tty->termios->c_cflag;
318
	}
319
320
	/* check that they really want us to change something */
321
	if (old_termios) {
322
	  if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
323
	    printk(KERN_DEBUG " - nothing to change...\n");
324
	    if (p_tty_mutex != NULL) {
325
	      mutex_unlock(p_tty_mutex);
326
	    }
327
	    return;
328
	  }
329
	}
330
331
	/* get the byte size */
332
	switch (cflag & CSIZE) {
333
	  case CS5:
334
	    printk(KERN_DEBUG " - data bits = 5\n");
335
	    break;
336
	  case CS6:
337
	    printk(KERN_DEBUG " - data bits = 6\n");
338
	    break;
339
	  case CS7:
340
	    printk(KERN_DEBUG " - data bits = 7\n");
341
	    break;
342
	  case CS8:
343
	  default:
344
	    printk(KERN_DEBUG " - data bits = 8\n");
345
	    break;
346
	}
347
348
	/* determine the parity */
349
	if (cflag & PARENB) {
350
	  if (cflag & PARODD) {
351
	    printk(KERN_DEBUG " - parity = odd\n");
352
	  }
353
	  else {
354
	    printk(KERN_DEBUG " - parity = even\n");
355
	  }
356
	}
357
	else {
358
	  printk(KERN_DEBUG " - parity = none\n");
359
	}
360
361
	/* figure out the stop bits requested */
362
	if (cflag & CSTOPB) {
363
	  printk(KERN_DEBUG " - stop bits = 2\n");
364
	}
365
	else {
366
	  printk(KERN_DEBUG " - stop bits = 1\n");
367
	}
368
369
	/* figure out the hardware flow control settings */
370
	if (cflag & CRTSCTS) {
371
	  printk(KERN_DEBUG " - RTS/CTS is enabled\n");
372
	}
373
	else {
374
	  printk(KERN_DEBUG " - RTS/CTS is disabled\n");
375
	}
376
377
	/* determine software flow control			*/
378
	/* if we are implementing XON/XOFF, set the start and 	*/
379
	/* stop character in the device				*/
380
	if (I_IXOFF(tty) || I_IXON(tty)) {
381
	  unsigned char stop_char  = STOP_CHAR(tty);
382
	  unsigned char start_char = START_CHAR(tty);
383
384
	  /* if we are implementing INBOUND XON/XOFF */
385
	  if (I_IXOFF(tty)) {
386
	    printk(KERN_DEBUG " - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", start_char, stop_char);
387
	  }
388
	  else {
389
	    printk(KERN_DEBUG" - INBOUND XON/XOFF is disabled");
390
	  }
391
	  /* if we are implementing OUTBOUND XON/XOFF */
392
	  if (I_IXON(tty)) {
393
	    printk(KERN_DEBUG" - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", start_char, stop_char);
394
	  }
395
	  else {
396
	    printk(KERN_DEBUG" - OUTBOUND XON/XOFF is disabled");
397
	  }
398
	}
399
400
	/* get the baud rate wanted */
401
	printk(KERN_DEBUG " - baud rate = %d", tty_get_baud_rate(tty));
402
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
403
	if (p_tty_mutex != NULL) {
404
	  mutex_unlock(p_tty_mutex);
405
	}
406
}
407
408
/* Our fake UART values */
409
#define MCR_DTR         0x01
410
#define MCR_RTS         0x02
411
#define MCR_LOOP        0x04
412
#define MSR_CTS         0x08
413
#define MSR_CD          0x10
414
#define MSR_RI          0x20
415
#define MSR_DSR         0x40
416
417
static int rdptty_tiocmget(struct tty_struct * tty, struct file * file) {
418
	struct rdp_port * rdp = (struct rdp_port *)NULL;
419
	unsigned int result = 0;
420
	unsigned int msr = 0;
421
	unsigned int mcr = 0;
422
423
	if (p_tty_mutex != NULL) {
424
	  mutex_lock(p_tty_mutex);
425
	}
426
	if (tty != NULL && tty->driver_data != NULL) {
427
	  rdp = (struct rdp_port *)(tty->driver_data);
428
429
	  mutex_lock(&(rdp->mut));
430
431
	  msr = rdp->msr;
432
	  mcr = rdp->mcr;
433
434
	  mutex_unlock(&(rdp->mut));
435
436
	  result = ((mcr & MCR_DTR)  ? TIOCM_DTR  : 0) |  /* DTR is set */
437
	     ((mcr & MCR_RTS)  ? TIOCM_RTS  : 0) |      /* RTS is set */
438
	     ((mcr & MCR_LOOP) ? TIOCM_LOOP : 0) |      /* LOOP is set */
439
	     ((msr & MSR_CTS)  ? TIOCM_CTS  : 0) |      /* CTS is set */
440
	     ((msr & MSR_CD)   ? TIOCM_CAR  : 0) |      /* Carrier detect is set*/
441
	     ((msr & MSR_RI)   ? TIOCM_RI   : 0) |      /* Ring Indicator is set */
442
	     ((msr & MSR_DSR)  ? TIOCM_DSR  : 0);       /* DSR is set */
443
	}
444
	if (p_tty_mutex != NULL) {
445
	  mutex_unlock(p_tty_mutex);
446
	}
447
448
	return result;
449
}
450
451
static int rdptty_tiocmset(struct tty_struct * tty, struct file * file, unsigned int set, unsigned int clear) {
452
	struct rdp_port * rdp = (struct rdp_port *)NULL;
453
	unsigned int mcr = 0;
454
455
	if (p_tty_mutex != NULL) {
456
	  mutex_lock(p_tty_mutex);
457
	}
458
	if (tty != NULL && tty->driver_data != NULL) {
459
	  rdp = (struct rdp_port *)tty->driver_data;
460
	  mcr = rdp->mcr;
461
462
	  if (set & TIOCM_RTS) {
463
	    mcr |= MCR_RTS;
464
	  }
465
	  if (set & TIOCM_DTR) {
466
	    mcr |= MCR_RTS;
467
	  }
468
469
	  if (clear & TIOCM_RTS) {
470
	    mcr &= ~MCR_RTS;
471
	  }
472
	  if (clear & TIOCM_DTR) {
473
	    mcr &= ~MCR_RTS;
474
	  }
475
476
	  /* set the new MCR value in the device */
477
	  rdp->mcr = mcr;
478
	}
479
	if (p_tty_mutex != NULL) {
480
	  mutex_unlock(p_tty_mutex);
481
	}
482
	return 0;
483
}
484
485
/*
486
static int rdptty_read_proc(char *page, char **start, off_t off, int count,
487
                          int *eof, void *data) {
488
	struct rdp_port * rdp = (struct rdp_port *)NULL;
489
	off_t begin = 0;
490
	int length = 0;
491
	int i = 0;
492
493
	length += sprintf(page, "rdpserinfo:1.0 driver:%s\n", DRIVER_VERSION);
494
	for (i = 0; i < RDP_TTY_MINORS && length < PAGE_SIZE; ++i) {
495
	  rdp = rdptty_table[i];
496
	  if (rdp == NULL) {
497
	    continue;
498
	  }
499
	  length += sprintf(page+length, "%d\n", i);
500
	  if ((length + begin) > (off + count)) {
501
	    goto done;
502
          }
503
	  if ((length + begin) < off) {
504
	    begin += length;
505
	    length = 0;
506
	  }
507
	}
508
	*eof = 1;
509
  done:
510
	if (off >= (length + begin)) {
511
	  return 0;
512
	}
513
	*start = page + (off-begin);
514
	return (count < begin+length-off) ? count : begin + length-off;
515
}
516
*/
517
518
#define rdptty_ioctl rdptty_ioctl_tiocgserial
519
static int rdptty_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) {
520
	struct rdp_port * rdp = (struct rdp_port *)NULL;
521
	int rv = -ENOIOCTLCMD;
522
523
	printk(KERN_INFO "INFO\t[%s()]: called", __FUNCTION__);
524
525
	if (p_tty_mutex != NULL) {
526
	  mutex_lock(p_tty_mutex);
527
	}
528
	if (tty != NULL && tty->driver_data != NULL) {
529
	  rdp = (struct rdp_port *)(tty->driver_data);
530
	  mutex_lock(&(rdp->mut));
531
	  if (cmd == TIOCGSERIAL) {
532
	    struct serial_struct tmp;
533
	    if (!arg) {
534
		rv = -EFAULT;
535
	    }
536
	    else {
537
		memset(&tmp, 0, sizeof(struct serial_struct));
538
		tmp.type                = rdp->serial.type;
539
		tmp.line                = rdp->serial.line;
540
		tmp.port                = rdp->serial.port;
541
		tmp.irq                 = rdp->serial.irq;
542
		tmp.flags               = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
543
		tmp.xmit_fifo_size      = rdp->serial.xmit_fifo_size;
544
		tmp.baud_base           = rdp->serial.baud_base;
545
		tmp.close_delay         = 5*HZ;
546
		tmp.closing_wait        = 30*HZ;
547
		tmp.custom_divisor      = rdp->serial.custom_divisor;
548
		tmp.hub6                = rdp->serial.hub6;
549
		tmp.io_type             = rdp->serial.io_type;
550
		if (copy_to_user((void __user *)arg, &tmp, sizeof(struct serial_struct))) {
551
		  rv = -EFAULT;
552
		}
553
		else {
554
		  rv = 0;
555
		}
556
	    }
557
	  }
558
	  mutex_unlock(&(rdp->mut));
559
	}
560
	if (p_tty_mutex != NULL) {
561
	  mutex_unlock(p_tty_mutex);
562
	}
563
	return rv;
564
}
565
#undef rdptty_ioctl
566
567
#define rdptty_ioctl rdptty_ioctl_tiocmiwait
568
static int rdptty_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) {
569
	struct rdp_port * rdp = (struct rdp_port *)NULL;
570
	int do_up = 1;
571
572
	printk(KERN_INFO "INFO\t[%s()]: called", __FUNCTION__);
573
574
	if (p_tty_mutex != NULL) {
575
	  mutex_lock(p_tty_mutex);
576
	}
577
	if (tty != NULL && tty->driver_data != NULL) {
578
	  rdp = (struct rdp_port *)(tty->driver_data);
579
	  mutex_lock(&(rdp->mut));
580
	  if (cmd == TIOCMIWAIT) {
581
		DECLARE_WAITQUEUE(wait, current);
582
		struct async_icount cnow;
583
		struct async_icount cprev;
584
585
		cprev = rdp->icount;
586
		mutex_unlock(&(rdp->mut));
587
		mutex_unlock(p_tty_mutex);
588
		do_up = 0;
589
		while (1) {
590
			add_wait_queue(&rdp->wait, &wait);
591
			set_current_state(TASK_INTERRUPTIBLE);
592
			schedule();
593
			remove_wait_queue(&rdp->wait, &wait);
594
595
			/* see if a signal woke us up */
596
			if (signal_pending(current)) {
597
			  return -ERESTARTSYS;
598
			}
599
600
			cnow = rdp->icount;
601
			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
602
			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
603
			  return -EIO; /* no change => error */
604
			}
605
			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
606
			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
607
			    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
608
			    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
609
			  return 0;
610
			}
611
			cprev = cnow;
612
                }
613
614
	  }
615
	  else {
616
		mutex_unlock(&(rdp->mut));
617
		mutex_unlock(p_tty_mutex);
618
		do_up = 0;
619
	  }
620
	}
621
	if (do_up > 0 && p_tty_mutex != NULL) {
622
	  mutex_unlock(p_tty_mutex);
623
	}
624
	return -ENOIOCTLCMD;
625
}
626
#undef rdptty_ioctl
627
628
#define rdptty_ioctl rdptty_ioctl_tiocgicount
629
static int rdptty_ioctl(struct tty_struct *tty, struct file *file,
630
                      unsigned int cmd, unsigned long arg) {
631
	struct rdp_port * rdp = (struct rdp_port *)NULL;
632
633
	printk(KERN_INFO "INFO\t[%s()]: called", __FUNCTION__);
634
635
	if (p_tty_mutex != NULL) {
636
	  mutex_lock(p_tty_mutex);
637
	}
638
	if (tty != NULL && tty->driver_data != NULL) {
639
	  rdp = (struct rdp_port *)(tty->driver_data);
640
	  mutex_lock(&(rdp->mut));
641
	  if (cmd == TIOCGICOUNT) {
642
                struct async_icount cnow = rdp->icount;
643
                struct serial_icounter_struct icount;
644
645
                icount.cts      = cnow.cts;
646
                icount.dsr      = cnow.dsr;
647
                icount.rng      = cnow.rng;
648
                icount.dcd      = cnow.dcd;
649
                icount.rx       = cnow.rx;
650
                icount.tx       = cnow.tx;
651
                icount.frame    = cnow.frame;
652
                icount.overrun  = cnow.overrun;
653
                icount.parity   = cnow.parity;
654
                icount.brk      = cnow.brk;
655
                icount.buf_overrun = cnow.buf_overrun;
656
657
                if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) {
658
			mutex_unlock(&(rdp->mut));
659
			mutex_unlock(p_tty_mutex);
660
			return -EFAULT;
661
		}
662
		else {
663
			mutex_unlock(&(rdp->mut));
664
			mutex_unlock(p_tty_mutex);
665
			return 0;
666
		}
667
	  }
668
	  mutex_unlock(&(rdp->mut));
669
	}
670
	if (p_tty_mutex != NULL) {
671
	  mutex_unlock(p_tty_mutex);
672
	}
673
	return -ENOIOCTLCMD;
674
}
675
#undef rdptty_ioctl
676
677
/* the real rdptty_ioctl function.  The above is done to get the small functions in the book */
678
static int rdptty_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) {
679
680
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
681
682
	switch (cmd) {
683
	  case TIOCGSERIAL:
684
	    return rdptty_ioctl_tiocgserial(tty, file, cmd, arg);
685
	    break;
686
	  case TIOCMIWAIT:
687
	    return rdptty_ioctl_tiocmiwait(tty, file, cmd, arg);
688
	    break;
689
	  case TIOCGICOUNT:
690
	    return rdptty_ioctl_tiocgicount(tty, file, cmd, arg);
691
	    break;
692
	}
693
694
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
695
	return -ENOIOCTLCMD;
696
}
697
698
static struct tty_operations serial_ops = {
699
	.open		= rdptty_open,
700
	.close		= rdptty_close,
701
	.put_char	= rdptty_putchar,
702
	.write		= rdptty_write,
703
	.write_room	= rdptty_write_room,
704
	.set_termios	= rdptty_set_termios,
705
	.tiocmget	= rdptty_tiocmget,
706
	.tiocmset	= rdptty_tiocmset,
707
	.ioctl		= rdptty_ioctl,
708
};
709
710
static struct tty_driver * rdptty_tty_driver = (struct tty_driver *)NULL;
711
712
int __init rdptty_init(void) {
713
	int retval = 0;
714
	int l_major = RDP_TTY_MAJOR;
715
	int l_minor = RDP_TTY_MINORS;
716
	char * l_name = (char *)RDP_TTY_NAME;
717
	char * l_dev = (char *)RDP_TTY_DEV;
718
719
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
720
721
	memset(&g_tty_mutex, 0x00, sizeof(struct mutex));
722
	p_tty_mutex = &g_tty_mutex;
723
	mutex_init(p_tty_mutex);
724
	mutex_lock(p_tty_mutex);
725
726
	if (major > 0) {
727
	  l_major = major;
728
	}
729
	if (minor > 0) {
730
	  l_minor = minor;
731
	}
732
	if (name != NULL && strlen(name) > 0 && strlen(name) < 33) {
733
	  l_name = name;
734
	}
735
	if (dev != NULL && strlen(dev) > 0 && strlen(dev) < 33) {
736
	  l_dev = dev;
737
	}
738
739
740
	/* allocate the tty driver */
741
	rdptty_tty_driver = alloc_tty_driver(l_minor);
742
	if (!rdptty_tty_driver) {
743
	  retval = -ENOMEM;
744
	  goto end;
745
	}
746
747
	memset(&rdp_tty_ops, 0, sizeof(struct tty_operations));
748
	rdp_ops_setup(&rdp_tty_ops);
749
750
	/* initialize the tty driver */
751
	rdptty_tty_driver->owner = THIS_MODULE;
752
	rdptty_tty_driver->driver_name = l_name;
753
	rdptty_tty_driver->name = l_dev;
754
	/* no more devfs subsystem */
755
	rdptty_tty_driver->major = l_major;
756
	rdptty_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
757
	rdptty_tty_driver->subtype = SERIAL_TYPE_NORMAL;
758
//	rdptty_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS;
759
	rdptty_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
760
	/* no more devfs subsystem */
761
	rdptty_tty_driver->init_termios = tty_std_termios;
762
	rdptty_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
763
764
	tty_set_operations(rdptty_tty_driver, &serial_ops);
765
766
	/* register the tty driver */
767
	retval = tty_register_driver(rdptty_tty_driver);
768
	if (retval) {
769
	  printk(KERN_ERR "failed to register rdp tty driver");
770
	  put_tty_driver(rdptty_tty_driver);
771
	}
772
	else {
773
	  rdp_init(rdptty_tty_driver, p_tty_mutex);
774
	  printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
775
	}
776
777
      end:;
778
	if (p_tty_mutex != NULL) {
779
	  mutex_unlock(p_tty_mutex);
780
	}
781
	return retval;
782
}
783
784
void __exit rdptty_exit(void) {
785
	int i = 0;
786
787
	printk(KERN_DEBUG "INFO\t[%s()]: called", __FUNCTION__);
788
789
	if (p_tty_mutex != NULL) {
790
	  mutex_lock(p_tty_mutex);
791
	}
792
793
	/* shut down all of the timers and free the memory */
794
	if (1==2) {
795
//	{
796
//	  struct rdptty_serial * rdp = (struct rdptty_serial *)NULL;
797
	  struct rdp_port * rdp = (struct rdp_port *)NULL;
798
	  for (i = 0; i < RDP_TTY_MINORS; ++i) {
799
		rdp = rdptty_table[i];
800
		if (rdp != NULL) {
801
//			mutex_lock(&(rdp->mut));
802
			/* close the port */
803
			while (atomic_read(&(rdp->open_count)) > 0) {
804
//			  do_close(rdp);
805
//			  if (rdp_tty_ops.close) {
806
//			    rdp_tty_ops.close(rdp->tty, NULL);
807
//			  }
808
			}
809
//			rdptty_table[i] = NULL;
810
//			mutex_unlock(&(rdp->mut));
811
		}
812
	  }
813
	}
814
815
	rdp_exit(rdptty_tty_driver);
816
	tty_unregister_driver(rdptty_tty_driver);
817
	put_tty_driver(rdptty_tty_driver);
818
	if (p_tty_mutex != NULL) {
819
	  mutex_unlock(p_tty_mutex);
820
	}
821
	p_tty_mutex = (struct mutex *)NULL;
822
823
	printk(KERN_DEBUG "INFO\t[%s()]: done.", __FUNCTION__);
824
}
825
826
module_init(rdptty_init);
827
module_exit(rdptty_exit);
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/drivers/serial/rdpuart.c (+1858 lines)
Line 0    Link Here 
1
/*
2
 * rdpuart.c: Virtual serial port driver for RDP
3
 *
4
 * Copyright (C) 2010, Ryan Rafferty.
5
 *
6
 * This file is licensed under the terms of the GNU General Public License
7
 * version 2.  This program is licensed "as is" without any warranty of any
8
 * kind, whether express or implied.
9
 */
10
11
#include <linux/platform_device.h>
12
#include <linux/module.h>
13
#include <linux/serial.h>
14
#include <linux/serial_core.h>
15
#include <linux/serial_reg.h>
16
#include <linux/tty.h>
17
#include <linux/delay.h>
18
#include <linux/interrupt.h>
19
#include <linux/init.h>
20
#include <linux/sched.h>
21
#include <linux/completion.h>
22
#include <linux/version.h>
23
#include <asm/io.h>
24
25
#include <linux/skbuff.h>
26
#include <linux/netlink.h>
27
#include <linux/connector.h>
28
29
#include <linux/spinlock.h>
30
#include <linux/list.h>
31
#include <linux/timer.h>
32
33
#include <linux/rdpuart.h>
34
35
#include "ntddser.h"
36
37
38
/***
39
 ***	Default constants for this module
40
 ***/
41
42
#define	RDPUART_TITLE		"rdpuart"
43
#define RDPUART_NAME		"ttyRDP"
44
#define RDPUART_MAJOR		240
45
#define RDPUART_MINOR		186
46
#define RDPUART_NR_UARTS	2
47
#define RDPUART_MAX_UARTS	32
48
#define RDPUART_ALIAS		"platform:rdpuart"
49
#define	RDPUART_NR_IRQ		0
50
51
/* ---------------------------------------------------------------------
52
 *
53
 * Register definitions
54
 *
55
 */
56
#ifndef LINUX_RDPUART_REGS
57
#define LINUX_RDPUART_REGS
58
59
#define RDPUART_RX		0x00
60
#define RDPUART_TX		0x04
61
#define RDPUART_STATUS		0x08
62
#define RDPUART_CONTROL		0x0c
63
64
#define RDPUART_REGION		16
65
66
#define RDPUART_STATUS_RXVALID	0x01
67
#define RDPUART_STATUS_RXFULL	0x02
68
#define RDPUART_STATUS_TXEMPTY	0x04
69
#define RDPUART_STATUS_TXFULL	0x08
70
#define RDPUART_STATUS_IE	0x10
71
#define RDPUART_STATUS_OVERRUN	0x20
72
#define RDPUART_STATUS_FRAME	0x40
73
#define RDPUART_STATUS_PARITY	0x80
74
75
#define RDPUART_CONTROL_RST_TX	0x01
76
#define RDPUART_CONTROL_RST_RX	0x02
77
#define RDPUART_CONTROL_IE	0x10
78
79
#endif	/*	LINUX_RDPUART_REGS	*/
80
81
82
/***
83
 ***	convenience macros
84
 ***/
85
86
#define is_real_interrupt(x) ((x == 0) ? x : 0)
87
88
#ifndef MINVAL
89
#define MINVAL(x,y) (((x) > (y)) ? (y) : (x))
90
#endif
91
92
#define ASCIICHR(x) (((x) > 31 && x < 127) ? x : 0x20)
93
#define DBGLOG(...) {				\
94
	printk(__VA_ARGS__);			\
95
	printk("\n");				\
96
}
97
#define RDPUARTCMD(x) (cmdarray[(x & 0x1f)])
98
static const char * cmdarray[] = CMD_TO_STRING_ARRAY_DEF;
99
100
101
/***
102
 ***	static function prototypes
103
 ***/
104
105
static int rdpuart_receive(struct rdpuart_port *, int, int, char *);
106
static int __devinit rdpuart_probe(struct platform_device *);
107
static int __devexit rdpuart_remove(struct platform_device *);
108
109
110
/***
111
 ***	static structs
112
 ***/
113
114
static struct platform_driver rdpuart_platform_driver = {
115
	.probe		= rdpuart_probe,
116
	.remove		= __devexit_p(rdpuart_remove),
117
	.driver		= {
118
		.owner = THIS_MODULE,
119
		.name  = RDPUART_TITLE,
120
	},
121
};
122
123
124
/***
125
 ***	static global variables
126
 ***/
127
128
static int g_already_opened = 0;
129
static int g_stop = 1;
130
static struct uart_port * g_port = (struct uart_port *)NULL;
131
static struct platform_device * gdev = (struct platform_device *)NULL;
132
static struct rdpuart_port rdpuart_ports[RDPUART_MAX_UARTS];
133
134
#define Q_NAME	"rdpuart_work_queue"
135
static int g_exit = 0;
136
static void rdpuart_cmdw_handler(struct work_struct *);
137
static struct workqueue_struct * g_cmdq;
138
static DECLARE_DELAYED_WORK(g_cmdw, rdpuart_cmdw_handler);
139
140
static int major = RDPUART_MAJOR;
141
static int minor = RDPUART_MINOR;
142
static int nr = RDPUART_NR_UARTS;
143
static char * title = RDPUART_TITLE;
144
static char * name = RDPUART_NAME;
145
146
module_param(major, int, 0744);
147
module_param(minor, int, 0744);
148
module_param(nr, int, 0744);
149
module_param(title, charp, 0744);
150
module_param(name, charp, 0744);
151
152
153
/***
154
 ***	Netlink Connection ("cn") functions
155
 ***/
156
157
static struct rdpuart_family rdpuart_default_family = {};
158
159
typedef struct rdpuart_cmd {
160
	unsigned char		cmd;
161
	void *			idata;
162
	int			ilen;
163
	void *			odata;
164
	int			olen;
165
166
	int			seqid;
167
	unsigned char		completed;
168
	struct list_head	list;
169
170
	struct rdpuart_record *	rec;
171
	struct rdpuart_port *	port;
172
173
	int			cmd_idx;
174
} rdpuart_cmd_t;
175
176
static DEFINE_SPINLOCK(rdpuart_cmd_outbound_flock);
177
static LIST_HEAD(rdpuart_outbound_cmd_list);
178
179
DEFINE_SPINLOCK(rdpuart_flock);
180
static LIST_HEAD(rdpuart_families);
181
182
static DEFINE_SPINLOCK(rdpuart_cmd_list_flock);
183
static LIST_HEAD(rdpuart_pending_cmd_list);
184
static DECLARE_WAIT_QUEUE_HEAD(pending_cmd_reply_waitq);
185
186
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
187
#  define	CBARGS	struct cn_msg * imsg, struct netlink_skb_parms * parms
188
#else
189
#  define	CBARGS	void * imsg
190
#endif
191
static void rdpuart_cn_callback(CBARGS) {
192
  int found = 0;
193
  int mlen = 0;
194
  uint8_t mtype = 0x00;
195
  struct cn_msg * msg = (struct cn_msg *)imsg;
196
  rdpuart_netlink_msg * m = (rdpuart_netlink_msg *)(msg + 1);
197
  if (msg == NULL) {
198
    DBGLOG(KERN_ERR "ERROR\t[rdpuart_cn_callback()]: msg is a null pointer");
199
  }
200
  else {
201
    DBGLOG(KERN_INFO "INFO\t[rdpuart_cn_callback()]: called");
202
    while (msg->len) {
203
      struct rdpuart_cmd * cmd = (struct rdpuart_cmd *)NULL;
204
      struct list_head * ent = (struct list_head *)NULL;
205
      struct list_head * n = (struct list_head *)NULL;
206
      rdpuart_reg_num id;
207
      memcpy(&id, m->id.id, sizeof(rdpuart_reg_num));
208
      //DBGLOG(KERN_INFO "INFO\t[%s()]: {cn_msg}              idx = \"%d\", val = \"%d\", seqid = \"%d\", ack = \"%d\", len = \"%d\";", __func__, msg->id.idx, msg->id.val, msg->seq, msg->ack, msg->len);
209
      //DBGLOG(KERN_INFO "INFO\t[%s()]: {rdpuart_netlink_msg} %02x-%012llx.%02x --> type = \"%02x\", len= \"%u\".", __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len);
210
      mtype |= m->type;
211
      mlen = m->len;
212
      if (msg->ack > 0) {
213
	//DBGLOG(KERN_INFO "INFO\t[%s()]: msg->ack = \"%d\"", __func__, msg->ack);
214
	spin_lock(&rdpuart_cmd_list_flock);
215
	list_for_each_safe(ent, n, &rdpuart_pending_cmd_list) {
216
	  cmd = list_entry(ent, struct rdpuart_cmd, list);
217
	  //DBGLOG(KERN_INFO "INFO\t[%s()]: (seqid = \"%d\")", __func__, cmd->seqid);
218
	  if (cmd->seqid == msg->seq) {
219
	    //DBGLOG(KERN_INFO "INFO\t[%s()]: seqid \"%d\" (cmd_idx = \"%d\") about to be marked \"completed\"", __func__, cmd->seqid, cmd->cmd_idx);
220
	    found = 1;
221
	    cmd->completed = 1;
222
	    spin_lock(&(cmd->port->cmd_lock));
223
	    cmd->port->cmd_array[(cmd->cmd_idx)] = 0;
224
	    spin_unlock(&(cmd->port->cmd_lock));
225
	    break;
226
	  }
227
	}
228
	spin_unlock(&rdpuart_cmd_list_flock);
229
	if (found > 0) {
230
	  wake_up_interruptible_all(&pending_cmd_reply_waitq);
231
	}
232
      }
233
      else if (mtype > 0) {
234
	/* if an unsolicited cn packet is received, then it should be handled as a
235
	 * "virtual interrupt" received from the userspace daemon; so, queue up an
236
	 * ersatz irq handler:
237
	 */
238
	struct rdpuart_irq_data * irq_data = (struct rdpuart_irq_data *)(m->data);
239
	mtype &= ~RDPUART_ASYNC;
240
	switch (mtype) {
241
	  case RDPUART_ADDPORT:
242
	    {
243
	      struct resource * tarr = (struct resource *)NULL;
244
	      struct resource * iomem = (struct resource *)NULL;
245
	      struct resource * irq = (struct resource *)NULL;
246
	      struct resource rarr[2];
247
	      memset(rarr,0,sizeof(struct resource)*2);
248
	      if (rarr == NULL) {
249
	      }
250
	      else {
251
		resource_size_t start = 0;
252
		resource_size_t end = 0;
253
		void * membuf = (void *)NULL;
254
		#if PAGE_SIZE > 3999
255
		membuf = (void *)get_zeroed_page(GFP_KERNEL);
256
		start = (resource_size_t)membuf;
257
		end = (resource_size_t)(membuf + PAGE_SIZE);
258
		#else
259
		membuf = kzalloc(4000, GFP_KERNEL);
260
		start = (resource_size_t)membuf;
261
		end = (resource_size_t)(membuf + 4000);
262
		#endif
263
		{
264
		  struct resource liomem = {
265
		    .start = start,
266
		    .end = end,
267
		    .flags = IORESOURCE_MEM,
268
		  };
269
		  struct resource lirq = {
270
		    .start = (resource_size_t)RDPUART_NR_IRQ,
271
		    .end = (resource_size_t)RDPUART_NR_IRQ,
272
		    .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
273
		  };
274
		  iomem = &(rarr[0]);
275
		  irq = &(rarr[1]);
276
		  memcpy(iomem,&liomem,sizeof(struct resource));
277
		  memcpy(irq,&lirq,sizeof(struct resource));
278
		}
279
	      }
280
	      tarr = (struct resource *)kzalloc(sizeof(rarr), GFP_KERNEL);
281
	      memcpy(tarr,rarr,sizeof(rarr));
282
	      DBGLOG(KERN_INFO "INFO\t[%s()]: calling platform_device_register_simple() {rdpuart_platform_driver.driver.bus = \"%p\"}", __func__, rdpuart_platform_driver.driver.bus);
283
	      if (!(gdev = platform_device_register_simple(title, -1, tarr, ARRAY_SIZE(rarr)))) {
284
		DBGLOG(KERN_ERR "ERROR\t[%s()]: platform_device_register_simple() failed", __func__);
285
	      }
286
	    }
287
	    break;
288
	  case RDPUART_RXFULL:
289
	    {
290
		int idx = 0;
291
		int found = 0;
292
		for (idx = 0; idx < nr; idx++) {
293
		  if (rdpuart_ports[idx].device_id == irq_data->device_id) {
294
		    found = 1;
295
		    break;
296
		  }
297
		}
298
		if (found > 0) {
299
		  rdpuart_receive(&(rdpuart_ports[idx]), RDPUART_STATUS_RXVALID, irq_data->rx_len, irq_data->rx_buf);
300
		}
301
		else {
302
		  rdpuart_receive(&(rdpuart_ports[0]), RDPUART_STATUS_RXVALID, irq_data->rx_len, irq_data->rx_buf);
303
		}
304
	    }
305
	    break;
306
	  default:
307
	    {
308
	      DBGLOG(KERN_WARNING "WARNING\t[%s()]: INTERRUPT --> unrecognized opcode (\"0x%02x\")", __func__, mtype);
309
	    }
310
	    break;
311
	}
312
      }
313
      msg->len -= sizeof(rdpuart_netlink_msg) + m->len;
314
      m = (rdpuart_netlink_msg *)(((u8 *)m) + m->len);
315
    }
316
  }
317
}
318
319
int rdpuart_netlink_send(struct rdpuart_record * dev, rdpuart_netlink_msg * msg, int memmode) {
320
	int rv = 0;
321
	//char buf[sizeof(struct cn_msg) + sizeof(rdpuart_netlink_msg)];
322
	char buf[512];
323
	struct cn_msg * m = (struct cn_msg *)buf;
324
	rdpuart_netlink_msg * w = (rdpuart_netlink_msg *)(m+1);
325
	DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
326
	if (dev == NULL) {
327
	  DBGLOG(KERN_WARNING "WARNING\t[%s()]: dev is a null pointer", __func__);
328
	  rv = -EINVAL;
329
	  goto end;
330
	}
331
	if (msg == NULL) {
332
	  DBGLOG(KERN_WARNING "WARNING\t[%s()]: msg is a null pointer", __func__);
333
	  rv = -EINVAL;
334
	  goto end;
335
	}
336
	memset(buf, 0, sizeof(buf));
337
	m->id.idx = CN_IDX_RDPUART;
338
	m->id.val = CN_VAL_RDPUART;
339
	spin_lock(&(dev->lock));
340
	m->seq = dev->seq++;
341
	spin_unlock(&(dev->lock));
342
	rv = m->seq;
343
	//if (m->len < sizeof(rdpuart_netlink_msg) || m->len > (sizeof(struct cn_msg) + sizeof(rdpuart_netlink_msg))) {
344
	//  m->len = sizeof(rdpuart_netlink_msg);
345
	//}
346
	m->len = sizeof(rdpuart_netlink_msg) + msg->len;
347
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call memcpy()...", __func__);
348
	memcpy(w, msg, m->len);
349
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call cn_netlink_send()... {m->len = \"%d\"}", __func__, m->len);
350
	cn_netlink_send(m, 0, memmode);
351
  end:
352
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\").", __func__, rv);
353
	return rv;
354
}
355
356
357
int rdpuart_init_netlink(void) {
358
	int rv = 0;
359
	struct cb_id rdpuart_id = {
360
		.idx		= CN_IDX_RDPUART,
361
		.val		= CN_VAL_RDPUART,
362
	};
363
	DBGLOG(KERN_INFO "INFO\t[rdpuart_init_netlink()]: called");
364
	rv = cn_add_callback(&rdpuart_id, "rdpuart", &rdpuart_cn_callback);
365
	return rv;
366
}
367
368
void rdpuart_stop_netlink(void) {
369
	struct cb_id rdpuart_id = {
370
		.idx		= CN_IDX_RDPUART,
371
		.val		= CN_VAL_RDPUART,
372
	};
373
	DBGLOG(KERN_INFO "INFO\t[rdpuart_stop_netlink()]: called");
374
	cn_del_callback(&rdpuart_id);
375
}
376
377
int rdpuart_register_family(struct rdpuart_family * newf) {
378
	struct list_head * ent = (struct list_head *)NULL;
379
	struct list_head * n = (struct list_head *)NULL;
380
	struct rdpuart_family * f = (struct rdpuart_family *)NULL;
381
	int ret = 0;
382
383
	spin_lock(&rdpuart_flock);
384
	list_for_each_safe(ent, n, &rdpuart_families) {
385
		f = list_entry(ent, struct rdpuart_family, family_entry);
386
		if (f->fid == newf->fid) {
387
			ret = -EEXIST;
388
			break;
389
		}
390
	}
391
392
	if (!ret) {
393
		atomic_set(&newf->refcnt, 0);
394
		newf->need_exit = 0;
395
		list_add_tail(&newf->family_entry, &rdpuart_families);
396
	}
397
	spin_unlock(&rdpuart_flock);
398
399
	return ret;
400
}
401
402
void rdpuart_unregister_family(struct rdpuart_family * fent) {
403
	struct list_head * ent = (struct list_head *)NULL;
404
	struct list_head * n = (struct list_head *)NULL;
405
	struct rdpuart_family * f  = (struct rdpuart_family *)NULL;
406
407
	spin_lock(&rdpuart_flock);
408
	list_for_each_safe(ent, n, &rdpuart_families) {
409
		f = list_entry(ent, struct rdpuart_family, family_entry);
410
		if (f->fid == fent->fid) {
411
			list_del(&fent->family_entry);
412
			break;
413
		}
414
	}
415
416
	fent->need_exit = 1;
417
418
	spin_unlock(&rdpuart_flock);
419
420
	while (atomic_read(&(fent->refcnt))) {
421
	  printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n", fent->fid, atomic_read(&fent->refcnt));
422
	  if (msleep_interruptible(1000)) {
423
	    flush_signals(current);
424
	  }
425
	}
426
}
427
428
/*
429
 * Should be called under rdpuart_flock held.
430
 */
431
struct rdpuart_family * rdpuart_family_registered(u8 fid) {
432
	struct list_head * ent = (struct list_head *)NULL;
433
	struct list_head * n = (struct list_head *)NULL;
434
	struct rdpuart_family * f = (struct rdpuart_family *)NULL;
435
	int ret = 0;
436
	list_for_each_safe(ent, n, &rdpuart_families) {
437
		f = list_entry(ent, struct rdpuart_family, family_entry);
438
		if (f->fid == fid) {
439
			ret = 1;
440
			break;
441
		}
442
	}
443
	return (ret) ? f : NULL;
444
}
445
446
void rdpuart_family_put(struct rdpuart_family * f) {
447
	spin_lock(&rdpuart_flock);
448
	__rdpuart_family_put(f);
449
	spin_unlock(&rdpuart_flock);
450
}
451
452
void __rdpuart_family_put(struct rdpuart_family * f) {
453
	if (atomic_dec_and_test(&f->refcnt)) {
454
		f->need_exit = 1;
455
	}
456
}
457
458
void rdpuart_family_get(struct rdpuart_family *f) {
459
	spin_lock(&rdpuart_flock);
460
	__rdpuart_family_get(f);
461
	spin_unlock(&rdpuart_flock);
462
}
463
464
void __rdpuart_family_get(struct rdpuart_family *f) {
465
	smp_mb__before_atomic_inc();
466
	atomic_inc(&f->refcnt);
467
	smp_mb__after_atomic_inc();
468
}
469
470
EXPORT_SYMBOL(rdpuart_family_get);
471
EXPORT_SYMBOL(rdpuart_family_put);
472
EXPORT_SYMBOL(rdpuart_family_registered);
473
EXPORT_SYMBOL(rdpuart_unregister_family);
474
EXPORT_SYMBOL(rdpuart_register_family);
475
476
477
static int cmd_output(struct rdpuart_cmd * rcmd, int memmode) {
478
	int rv = 0;
479
	struct rdpuart_record * rec = NULL;
480
	struct rdpuart_family * f = NULL;
481
	unsigned char * cbuf = (unsigned char *)NULL;
482
	void * data = (void *)NULL;
483
	int len = 0;
484
	rdpuart_netlink_msg msg;
485
	unsigned char cmd = 0x00;
486
	struct rdpuart_port * port = (struct rdpuart_port *)NULL;
487
	int ilen = 0;
488
	int olen = 0;
489
	void * idata = (void *)NULL;
490
	void * odata = (void *)NULL;
491
	uint32_t cmd_idx = 0x00000000;
492
493
	if (rcmd == NULL) {
494
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: rcmd is a NULL pointer", __func__);
495
	  rv = -EINVAL;
496
	  goto end;
497
	}
498
	else {
499
	  port = rcmd->port;
500
	  cmd = rcmd->cmd;
501
	  ilen = rcmd->ilen;
502
	  olen = rcmd->olen;
503
	  idata = rcmd->idata;
504
	  odata = rcmd->odata;
505
	  len = ilen;
506
	  data = idata;
507
	  cmd_idx = rcmd->cmd_idx;
508
	}
509
	if (port == NULL) {
510
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: port is a NULL pointer", __func__);
511
	  rv = -EINVAL;
512
	  goto end;
513
	}
514
	else if (ilen > 0 && idata == NULL) {
515
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: idata is a NULL pointer", __func__);
516
	  rv = -EINVAL;
517
	  goto end;
518
	}
519
	else if (olen > 0 && odata == NULL) {
520
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: odata is a NULL pointer", __func__);
521
	  rv = -ENOMEM;
522
	  goto end;
523
	}
524
525
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", idata = \"%p\", ilen = \"%d\", odata = \"%p\", olen = \"%d\")", __func__, RDPUARTCMD(cmd), idata, ilen, odata, olen);
526
527
	rec = &(port->rec);
528
529
	memset(&msg, 0, sizeof(rdpuart_netlink_msg));
530
	atomic_set(&(rec->refcnt), 0);
531
	init_completion(&(rec->released));
532
533
	spin_lock(&rdpuart_flock);
534
	f = &rdpuart_default_family;
535
	__rdpuart_family_get(f);
536
	rec->family = f;
537
538
	msg.type = cmd;
539
540
	if (len > 0 && data != NULL) {
541
	  msg.len = len + sizeof(uint32_t);
542
	  cbuf = (unsigned char *)kzalloc((sizeof(rdpuart_netlink_msg) + len), memmode);
543
	  if (cbuf == NULL) {
544
	    rv = -ENOMEM;
545
	    goto end;
546
	  }
547
	  else {
548
	    rdpuart_netlink_msg * pm = (rdpuart_netlink_msg *)cbuf;
549
	    uint32_t * pn = (uint32_t *)(pm+1);
550
	    unsigned char * pd = (unsigned char *)(pn+1);
551
	    memcpy(pm, &msg, sizeof(rdpuart_netlink_msg));
552
	    memcpy(pn, &cmd_idx, sizeof(uint32_t));
553
	    memcpy(pd, data, len);
554
	  }
555
	}
556
	else {
557
	  cbuf = (unsigned char *)kzalloc((sizeof(rdpuart_netlink_msg) + sizeof(uint32_t)), memmode);
558
	  if (cbuf == NULL) {
559
	    rv = -ENOMEM;
560
	    goto end;
561
	  }
562
	  else {
563
	    rdpuart_netlink_msg * pm = (rdpuart_netlink_msg *)cbuf;
564
	    uint32_t * pn = (uint32_t *)(pm+1);
565
	    memcpy(pm, &msg, sizeof(rdpuart_netlink_msg));
566
	    memcpy(pn, &cmd_idx, sizeof(uint32_t));
567
	  }
568
	}
569
	rv = rdpuart_netlink_send(rec, (void *)cbuf, memmode);
570
	spin_unlock(&rdpuart_flock);
571
	if (rv < 0) {
572
	  goto unlock;
573
	}
574
	else {
575
	  struct rdpuart_cmd * lcmd = (struct rdpuart_cmd *)kzalloc(sizeof(struct rdpuart_cmd), memmode);
576
	  if (lcmd == NULL) {
577
	    rv = -ENOMEM;
578
	    goto unlock;
579
	  }
580
	  lcmd->cmd = cmd;
581
	  lcmd->idata = idata;
582
	  lcmd->ilen = ilen;
583
	  lcmd->odata = odata;
584
	  lcmd->olen = olen;
585
	  lcmd->seqid = rv;
586
	  lcmd->completed = 0;
587
	  lcmd->port = port;
588
	  lcmd->rec = rec;
589
	  lcmd->cmd_idx = rcmd->cmd_idx;
590
	  spin_lock(&rdpuart_cmd_list_flock);
591
	  list_add_tail(&(lcmd->list), &rdpuart_pending_cmd_list);
592
	  spin_unlock(&rdpuart_cmd_list_flock);
593
	}
594
595
  unlock:
596
	if (cbuf != NULL) {
597
	  kfree(cbuf);
598
	}
599
600
  end:
601
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\")", __func__, rv);
602
	return rv;
603
}
604
605
static struct list_head * cmd_enq(struct rdpuart_cmd * rcmd) {
606
  unsigned long flags;
607
  struct list_head * rv = &rdpuart_outbound_cmd_list;
608
609
  spin_lock_irqsave(&rdpuart_cmd_outbound_flock, flags);
610
611
  list_add_tail(&(rcmd->list), &rdpuart_outbound_cmd_list);
612
613
  spin_unlock_irqrestore(&rdpuart_cmd_outbound_flock, flags);
614
615
  return rv;
616
}
617
618
static struct rdpuart_cmd * cmd_deq(struct rdpuart_cmd ** rcmd) {
619
  unsigned long flags;
620
  struct rdpuart_cmd * cmd = (struct rdpuart_cmd *)NULL;
621
622
  spin_lock_irqsave(&rdpuart_cmd_outbound_flock, flags);
623
624
  if (!list_empty(&rdpuart_outbound_cmd_list)) {
625
    cmd = list_entry(rdpuart_outbound_cmd_list.next, struct rdpuart_cmd, list);
626
    list_del(&(cmd->list));
627
  }
628
  if (rcmd != NULL) {
629
    *rcmd = cmd;
630
  }
631
632
  spin_unlock_irqrestore(&rdpuart_cmd_outbound_flock, flags);
633
634
  return cmd;
635
}
636
637
static int cmd_process_list(struct list_head * cmdlist) {
638
  int rv = 0;
639
  struct rdpuart_cmd * cmd = (struct rdpuart_cmd *)NULL;
640
641
  DBGLOG(KERN_INFO "INFO\t[%s()]: called", __func__);
642
643
  do {
644
    cmd_deq(&cmd);
645
    if (cmd != NULL) {
646
      DBGLOG(KERN_INFO "INFO\t[%s()]: outputting RDP command", __func__);
647
      cmd_output(cmd, GFP_KERNEL);
648
    }
649
  } while (cmd != NULL);
650
651
  DBGLOG(KERN_INFO "INFO\t[%s()]: done.", __func__);
652
653
  return rv;
654
}
655
656
static int cmd_is_completed(int seqid, struct rdpuart_cmd ** rcmd) {
657
	int rv = 0;
658
	int found = 0;
659
	struct list_head * ent = (struct list_head *)NULL;
660
	struct list_head * n = (struct list_head *)NULL;
661
	struct rdpuart_cmd * cmd = (struct rdpuart_cmd *)NULL;
662
663
	//spin_lock(&rdpuart_cmd_list_flock);
664
	/*
665
	 * iterate through the queue of issued cmds and check their "completed"
666
	 * status.  If completed, return "1"; otherwise, return "0".
667
	 */
668
	list_for_each_safe(ent, n, &rdpuart_pending_cmd_list) {
669
	  cmd = list_entry(ent, struct rdpuart_cmd, list);
670
	  if (cmd->seqid == seqid) {
671
	    found = 1;
672
	    rv = (cmd->completed > 0) ? 1 : 0;
673
	    DBGLOG(KERN_INFO "found --> seqid = %d; rv = %d", seqid, rv);
674
	    if (rv > 0) {
675
	      if (rcmd != NULL && *rcmd != NULL && cmd != NULL) {
676
		memcpy(*rcmd, cmd, sizeof(struct rdpuart_cmd));
677
		//if (cmd->olen > 0 && (*rcmd)->olen > 0 && cmd->odata != NULL && (*rcmd)->odata != cmd->odata) {
678
		//  memcpy((*rcmd)->odata, cmd->odata, MINVAL((*rcmd)->olen, cmd->olen));
679
		//}
680
		//memset(&((*rcmd)->list), 0, sizeof(struct list_head));
681
	      }
682
	      list_del(ent);
683
	      if (cmd != NULL) {
684
		/*
685
		 * ensure the data referenced by idata and odata are
686
		 * not prematurely freed, because these may be required
687
		 * for return-value processing:
688
		 */
689
		cmd->idata = (void *)NULL;
690
		cmd->odata = (void *)NULL;
691
		//memset(cmd, 0, sizeof(struct rdpuart_cmd));
692
		/*
693
		 * nonetheless, aside from the above entries, this "cmd"
694
		 * struct itself is no longer needed, so return it to the
695
		 * available memory pool:
696
		 */
697
		kfree(cmd);
698
		cmd = (struct rdpuart_cmd *)NULL;
699
	      }
700
	    }
701
	    break;
702
	  }
703
	  else {
704
	  }
705
	}
706
	if (found < 1) {
707
	  /*
708
	   * if the value of "found" is not set to "1", then no
709
	   * list entry having a seqid equal to the input value
710
	   * was encountered in the preceding list traversal;
711
	   * therefore, return an appropriate error code:
712
	   */
713
	  //rv = -1;
714
	  DBGLOG(KERN_WARNING "WARN\t[%s()]: found < 1", __func__);
715
	}
716
717
	//spin_unlock(&rdpuart_cmd_list_flock);
718
	return rv;
719
}
720
721
static int cmd_exec(struct rdpuart_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen) {
722
	int rv = 0;
723
	int seqid = 0;
724
	int cmd_idx = 0;
725
	int found = 0;
726
	const unsigned int max_timeout = 1800;	/* in jiffies: 1 jiffy = 0.004 sec	*/
727
	struct rdpuart_cmd * rcmd = (struct rdpuart_cmd *)NULL;
728
	struct rdpuart_cmd * lcmd = (struct rdpuart_cmd *)NULL;
729
	DECLARE_WAITQUEUE(wait, current);
730
731
	might_sleep();
732
733
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", ilen = \"%d\", olen = \"%d\")", __func__, RDPUARTCMD(cmd), ilen, olen);
734
735
	spin_lock(&(port->cmd_lock));
736
	for (cmd_idx = CMD_OFFSET; cmd_idx < CMD_MAX; cmd_idx++) {
737
	  if (port->cmd_array[cmd_idx] == 0) {
738
	    port->cmd_array[cmd_idx] = 1;
739
	    found = 1;
740
	    break;
741
	  }
742
	}
743
	spin_unlock(&(port->cmd_lock));
744
745
	if (found != 1) {
746
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: found != 1", __func__);
747
	  rv = -ENOMEM;
748
	  goto end;
749
	}
750
	else if (cmd_idx > CMD_MAX || cmd_idx < CMD_OFFSET) {
751
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: cmd_idx out of bounds (=\"%d\")", __func__, cmd_idx);
752
	  rv = -EINVAL;
753
	  goto end;
754
	}
755
756
	rcmd = (struct rdpuart_cmd *)kzalloc(sizeof(struct rdpuart_cmd), GFP_KERNEL);
757
	lcmd = (struct rdpuart_cmd *)kzalloc(sizeof(struct rdpuart_cmd), GFP_KERNEL);
758
759
	if (rcmd == NULL) {
760
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: rcmd == NULL", __func__);
761
	  rv = -ENOMEM;
762
	  goto end;
763
	}
764
	else if (lcmd == NULL) {
765
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: lcmd == NULL", __func__);
766
	  rv = -ENOMEM;
767
	  goto end;
768
	}
769
770
	lcmd->cmd = cmd;
771
	lcmd->port = port;
772
	lcmd->idata = idata;
773
	lcmd->ilen = ilen;
774
	lcmd->odata = odata;
775
	lcmd->olen = olen;
776
	lcmd->cmd_idx = cmd_idx;
777
778
	add_wait_queue(&pending_cmd_reply_waitq, &wait);
779
	seqid = cmd_output(lcmd, GFP_KERNEL);
780
781
	wait_event_interruptible_timeout(pending_cmd_reply_waitq, (cmd_is_completed(seqid, &rcmd)), max_timeout);
782
	remove_wait_queue(&pending_cmd_reply_waitq, &wait);
783
784
	spin_lock(&(port->cmd_lock));
785
	port->cmd_array[cmd_idx] = 0;
786
	spin_unlock(&(port->cmd_lock));
787
788
	if (rcmd != NULL && rcmd->olen > 0 && rcmd->odata != NULL && olen > 0 && odata != NULL && odata != rcmd->odata) {
789
	  memcpy(odata, rcmd->odata, olen);
790
	  //memcpy(odata, rcmd->odata, MINVAL(olen,rcmd->olen));
791
	  //kfree(rcmd->odata);
792
	}
793
	if (rcmd != NULL) {
794
	  kfree(rcmd);
795
	}
796
	if (lcmd != NULL) {
797
	  kfree(lcmd);
798
	}
799
800
  end:
801
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\", seqid = \"%d\").", __func__, rv, seqid);
802
	return rv;
803
}
804
805
static int cmd_send(struct rdpuart_port * port, unsigned char cmd, void * idata, int ilen, void * odata, int olen) {
806
	int rv = 0;
807
	int seqid = 0;
808
	int cmd_idx = 0;
809
	int found = 0;
810
	struct rdpuart_cmd * rcmd = (struct rdpuart_cmd *)NULL;
811
	struct rdpuart_cmd * lcmd = (struct rdpuart_cmd *)NULL;
812
813
	might_sleep();
814
815
	DBGLOG(KERN_INFO "INFO\t[%s()]: called (cmd = \"%s\", ilen = \"%d\", olen = \"%d\")", __func__, RDPUARTCMD(cmd), ilen, olen);
816
817
	spin_lock(&(port->cmd_lock));
818
	for (cmd_idx = CMD_OFFSET; cmd_idx < CMD_MAX; cmd_idx++) {
819
	  if (port->cmd_array[cmd_idx] == 0) {
820
	    port->cmd_array[cmd_idx] = 1;
821
	    found = 1;
822
	    break;
823
	  }
824
	}
825
	spin_unlock(&(port->cmd_lock));
826
827
	if (found != 1) {
828
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: found != 1", __func__);
829
	  rv = -ENOMEM;
830
	  goto end;
831
	}
832
	else if (cmd_idx > CMD_MAX || cmd_idx < CMD_OFFSET) {
833
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: cmd_idx out of bounds (=\"%d\")", __func__, cmd_idx);
834
	  rv = -EINVAL;
835
	  goto end;
836
	}
837
838
	rcmd = (struct rdpuart_cmd *)kzalloc(sizeof(struct rdpuart_cmd), GFP_ATOMIC);
839
	lcmd = (struct rdpuart_cmd *)kzalloc(sizeof(struct rdpuart_cmd), GFP_ATOMIC);
840
841
	if (rcmd == NULL) {
842
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: rcmd == NULL", __func__);
843
	  rv = -ENOMEM;
844
	  goto end;
845
	}
846
	else if (lcmd == NULL) {
847
	  DBGLOG(KERN_ERR "ERROR\t[%s()]: lcmd == NULL", __func__);
848
	  rv = -ENOMEM;
849
	  goto end;
850
	}
851
852
	lcmd->cmd = cmd;
853
	lcmd->port = port;
854
	lcmd->idata = idata;
855
	lcmd->ilen = ilen;
856
	lcmd->odata = (void *)vmalloc(olen);
857
	lcmd->olen = olen;
858
	lcmd->cmd_idx = cmd_idx;
859
860
	//seqid = cmd_output(lcmd, GFP_ATOMIC);
861
	cmd_enq(lcmd);
862
863
	spin_lock(&(port->cmd_lock));
864
	port->cmd_array[cmd_idx] = 0;
865
	spin_unlock(&(port->cmd_lock));
866
867
	queue_delayed_work(g_cmdq, &g_cmdw, 100);
868
869
  end:
870
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (rv = \"%d\", seqid = \"%d\").", __func__, rv, seqid);
871
	return rv;
872
}
873
874
875
/***
876
 ***	Functions for simulating "readb()" and "writeb()"
877
 ***/
878
879
/*
880
static unsigned char rdp_readb(unsigned char * loc) {
881
  unsigned char rv = *loc;
882
883
  DBGLOG(KERN_INFO "INFO\t[rdp_readb()]: called (loc = \"%p\", rv = [%d == \"%c\"])", loc, rv, ASCIICHR(rv));
884
885
  //cmd_exec(port, RDPUART_READ, (void *)loc, 1, NULL, 0);
886
887
  return rv;
888
}
889
*/
890
891
static int rdp_writeb(unsigned char ch, unsigned char * dest) {
892
  int rv = 0;
893
894
  *dest = ch;
895
896
  DBGLOG(KERN_INFO "INFO\t[rdp_writeb()]: called (dest = \"%p\", *dest = [%d == \"%c\"], ch = [%d == \"%c\"])", dest, *dest, ASCIICHR(*dest), ch, ASCIICHR(ch));
897
898
  //cmd_exec(port, RDPUART_WRITE, (void *)dest, 1, NULL, 0);
899
900
  return rv;
901
}
902
903
#ifdef DOIRQ
904
905
static int rdpuart_request_irq(int irq, irqreturn_t (*isr)(int, void *), int flags, const char * devname, struct uart_port * port) {
906
  int rv = 0;
907
908
  if (irq > 0) {
909
    rv = request_irq(irq, isr, flags, devname, port);
910
  }
911
912
  return rv;
913
}
914
915
static void rdpuart_free_irq(int irq, struct uart_port * port) {
916
  if (irq > 0 && port != NULL) {
917
    free_irq(irq, port);
918
  }
919
}
920
921
#endif
922
923
924
/* ---------------------------------------------------------------------
925
 *	Core UART driver operations
926
 */
927
928
static int rdpuart_receive(struct rdpuart_port * iport, int stat, int buflen, char * buf) {
929
	int rv = 1;
930
	char flag = TTY_NORMAL;
931
	unsigned char ch = 0;
932
	struct uart_port * port = &(iport->port);
933
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
934
	struct tty_struct * tty = port->state->port.tty;
935
#else
936
	struct tty_struct * tty = port->info->port.tty;
937
#endif
938
939
	DBGLOG(KERN_INFO "INFO\t[rdpuart_receive()]: called (stat = \"%d\", buflen = \"%d\")", stat, buflen);
940
941
	if (stat != 0 && !(stat & (RDPUART_STATUS_RXVALID | RDPUART_STATUS_OVERRUN | RDPUART_STATUS_FRAME))) {
942
	  rv = 0;
943
	  goto end;
944
	}
945
946
	/* stats */
947
	if (stat & RDPUART_STATUS_RXVALID) {
948
	  port->icount.rx++;
949
	  if (buflen > 0 && buf != NULL) {
950
	    ch = buf[0];
951
	  }
952
	  DBGLOG(KERN_INFO "INFO\t[%s()]: ch = %d", __func__, ch);
953
	  if (stat & RDPUART_STATUS_PARITY) {
954
	    port->icount.parity++;
955
	  }
956
	}
957
958
	if (stat & RDPUART_STATUS_OVERRUN) {
959
	  port->icount.overrun++;
960
	}
961
962
	if (stat & RDPUART_STATUS_FRAME) {
963
	  port->icount.frame++;
964
	}
965
966
	/* drop byte with parity error if IGNPAR specificed */
967
	if (stat & port->ignore_status_mask & RDPUART_STATUS_PARITY) {
968
	  stat &= ~RDPUART_STATUS_RXVALID;
969
	}
970
971
	stat &= port->read_status_mask;
972
973
	if (stat & RDPUART_STATUS_PARITY) {
974
	  flag = TTY_PARITY;
975
	}
976
977
	stat &= ~port->ignore_status_mask;
978
979
	if (stat & RDPUART_STATUS_RXVALID) {
980
	  tty_insert_flip_char(tty, ch, flag);
981
	}
982
983
	if (stat & RDPUART_STATUS_FRAME) {
984
	  tty_insert_flip_char(tty, 0, TTY_FRAME);
985
	}
986
987
	if (stat & RDPUART_STATUS_OVERRUN) {
988
	  tty_insert_flip_char(tty, 0, TTY_OVERRUN);
989
	}
990
991
	tty_flip_buffer_push(port->state->port.tty);
992
993
  end:
994
	return rv;
995
}
996
997
static int rdpuart_transmit(struct rdpuart_port * iport, int stat) {
998
	int rv = 1;
999
	struct uart_port * port = &(iport->port);
1000
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
1001
	struct circ_buf *xmit  = &port->state->xmit;
1002
#else
1003
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,27)
1004
	struct circ_buf *xmit  = &port->info->xmit;
1005
#else
1006
	struct circ_buf *xmit  = &port->info->xmit;
1007
#endif
1008
#endif
1009
1010
	might_sleep();
1011
1012
	DBGLOG(KERN_INFO "INFO\t[rdpuart_transmit()]: called (stat = \"%d\")", stat);
1013
1014
	if (stat & RDPUART_STATUS_TXFULL) {
1015
	  rv = 0;
1016
	  goto end;
1017
	}
1018
1019
	if (port->x_char) {
1020
	  rdp_writeb(port->x_char, port->membase + RDPUART_TX);
1021
	  port->x_char = 0;
1022
	  port->icount.tx++;
1023
	  rv = 1;
1024
	  goto end;
1025
	}
1026
1027
	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
1028
	  rv = 0;
1029
	  goto end;
1030
	}
1031
1032
	//rdp_writeb(xmit->buf[xmit->tail], port->membase + RDPUART_TX);
1033
	cmd_exec(iport, RDPUART_WRITE, &(xmit->buf[xmit->tail]), 1, NULL, 0);
1034
	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
1035
	port->icount.tx++;
1036
1037
	/* wake up */
1038
	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
1039
	  uart_write_wakeup(port);
1040
	}
1041
1042
  end:
1043
	return rv;
1044
}
1045
1046
#ifdef DOIRQ
1047
static irqreturn_t rdpuart_isr(int irq, void * dev_id) {
1048
	int busy = 0;
1049
	struct uart_port * port = dev_id;
1050
1051
	/* DBGLOG(KERN_INFO "INFO\t[rdpuart_isr()]: called (irq = %d)", irq);	*/
1052
1053
	do {
1054
	  int stat = rdp_readb(port->membase + RDPUART_STATUS);
1055
	  busy  = rdpuart_receive(port, stat);
1056
	  busy |= rdpuart_transmit(port, stat);
1057
	} while (busy);
1058
1059
	/* raise_softirq(irq);	*/
1060
1061
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
1062
	tty_flip_buffer_push(port->state->port.tty);
1063
#else
1064
	tty_flip_buffer_push(port->info->port.tty);
1065
#endif
1066
1067
	return IRQ_HANDLED;
1068
}
1069
#endif
1070
1071
static unsigned int rdpuart_tx_empty(struct rdpuart_port * port) {
1072
	unsigned int ret = 0;
1073
	unsigned char res = 0;
1074
1075
	might_sleep();
1076
1077
	DBGLOG(KERN_INFO "INFO\t[rdpuart_tx_empty()]: called");
1078
1079
	cmd_exec(port, RDPUART_TXEMPTY, NULL, 0, &res, sizeof(unsigned char));
1080
	//res = 1;
1081
	ret = (res == 1) ? TIOCSER_TEMT : 0;
1082
	return ret;
1083
}
1084
1085
static unsigned int rdpuart_get_mctrl(struct rdpuart_port * port) {
1086
	unsigned int rv = 0;
1087
	unsigned char status = 0;
1088
1089
	might_sleep();
1090
1091
	DBGLOG(KERN_INFO "INFO\t[rdpuart_get_mctrl()]: called");
1092
1093
	//rv = port->mctrl | TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
1094
	//cmd_exec(port, RDPUART_GETMCTRL, NULL, 0, &status, sizeof(status));
1095
	//return rv;
1096
1097
	if (g_already_opened > 0) {
1098
	  //cmd_exec(port, RDPUART_GETMCTRL, NULL, 0, &status, sizeof(status));
1099
	  status |= port->port.mctrl;
1100
	  if (status & UART_MSR_DCD) {
1101
		rv |= TIOCM_CAR;
1102
	  }
1103
	  if (status & UART_MSR_RI) {
1104
		rv |= TIOCM_RNG;
1105
	  }
1106
	  if (status & UART_MSR_DSR) {
1107
		rv |= TIOCM_DSR;
1108
	  }
1109
	  if (status & UART_MSR_CTS) {
1110
		rv |= TIOCM_CTS;
1111
	  }
1112
	}
1113
	else {
1114
	  rv |= TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
1115
	}
1116
	//port->port.mctrl = status;
1117
1118
	return rv;
1119
}
1120
1121
static void rdpuart_set_mctrl(struct rdpuart_port * port, unsigned int mctrl) {
1122
	uint8_t mcr = 0x00;
1123
	uint32_t omcr = 0x00000000;
1124
	//uint16_t omcr = 0x0000;
1125
1126
	DBGLOG(KERN_INFO "INFO\t[rdpuart_set_mctrl()]: called (mctrl = \"0x%8.8x\")", mctrl);
1127
1128
	if (mctrl & TIOCM_RTS) {
1129
		mcr |= UART_MCR_RTS;
1130
	}
1131
	if (mctrl & TIOCM_DTR) {
1132
		mcr |= UART_MCR_DTR;
1133
	}
1134
	if (mctrl & TIOCM_LOOP) {
1135
		mcr |= UART_MCR_LOOP;
1136
	}
1137
1138
	omcr |= mcr;
1139
	port->port.mctrl = 0;
1140
	port->port.mctrl |= mctrl;
1141
1142
	if (g_already_opened > 0) {
1143
	  //might_sleep();
1144
	  //cmd_exec(port, RDPUART_SETMCTRL, &(omcr), sizeof(omcr), NULL, 0);
1145
	  //cmd_exec(port, RDPUART_SETMCTRL, &(mcr), sizeof(mcr), NULL, 0);
1146
	  //cmd_send(port, RDPUART_SETMCTRL, &(mcr), sizeof(mcr), NULL, 0);
1147
	  cmd_send(port, RDPUART_SETMCTRL, &(mcr), sizeof(mcr), NULL, 0);
1148
	}
1149
}
1150
1151
static void rdpuart_stop_tx(struct rdpuart_port * port) {
1152
1153
	DBGLOG(KERN_INFO "INFO\t[rdpuart_stop_tx()]: called");
1154
1155
	//cmd_exec(port, RDPUART_TXSTOP, NULL, 0, NULL, 0);
1156
}
1157
1158
static void rdpuart_start_tx(struct rdpuart_port * port) {
1159
1160
	DBGLOG(KERN_INFO "INFO\t[rdpuart_start_tx()]: called");
1161
1162
	//rdpuart_transmit(port, rdp_readb(port->membase + RDPUART_STATUS));
1163
	//cmd_exec(port, RDPUART_TXSTART, NULL, 0, NULL, 0);
1164
1165
	rdpuart_transmit(port, 0);
1166
}
1167
1168
static void rdpuart_stop_rx(struct rdpuart_port * port) {
1169
1170
	DBGLOG(KERN_INFO "INFO\t[rdpuart_stop_rx()]: called");
1171
1172
	/* don't forward any more data (like !CREAD) */
1173
	port->port.ignore_status_mask = RDPUART_STATUS_RXVALID | RDPUART_STATUS_PARITY
1174
		| RDPUART_STATUS_FRAME | RDPUART_STATUS_OVERRUN;
1175
1176
	//cmd_exec(port, RDPUART_RXSTOP, NULL, 0, NULL, 0);
1177
}
1178
1179
static void rdpuart_enable_ms(struct rdpuart_port * port) {
1180
1181
	might_sleep();
1182
1183
	DBGLOG(KERN_INFO "INFO\t[rdpuart_enable_ms()]: called");
1184
1185
	cmd_exec(port, RDPUART_MSENABLE, NULL, 0, NULL, 0);
1186
	/* N/A */
1187
}
1188
1189
static void rdpuart_break_ctl(struct rdpuart_port * port, int ctl) {
1190
1191
	might_sleep();
1192
1193
	DBGLOG(KERN_INFO "INFO\t[rdpuart_break_ctl()]: called (ctl = \"%d\")", ctl);
1194
1195
	cmd_exec(port, RDPUART_BREAKCTL, NULL, 0, NULL, 0);
1196
	/* N/A */
1197
}
1198
1199
static int rdpuart_startup(struct rdpuart_port * port) {
1200
	int rv = 0;
1201
	uint32_t fd = 0x00000000;
1202
1203
	might_sleep();
1204
1205
	DBGLOG(KERN_INFO "INFO\t[rdpuart_startup()]: called");
1206
1207
	//if (!(ret = rdpuart_request_irq(port->irq, rdpuart_isr, IRQF_DISABLED | IRQF_SAMPLE_RANDOM, title, port))) {
1208
	  //rdp_writeb(RDPUART_CONTROL_RST_RX | RDPUART_CONTROL_RST_TX, port->membase + RDPUART_CONTROL);
1209
	  //rdp_writeb(RDPUART_CONTROL_IE, port->membase + RDPUART_CONTROL);
1210
	//}
1211
1212
	//DBGLOG(KERN_INFO "INFO\t[rdpuart_startup()]: ret = \"%d\"", ret);
1213
1214
	cmd_exec(port, RDPUART_OPEN, NULL, 0, &fd, sizeof(fd));
1215
	//if (fd > 0) {
1216
	  g_already_opened++;
1217
	//}
1218
1219
	if (g_already_opened == 1) {
1220
	  g_stop = 0;
1221
	  cmd_exec(port, RDPUART_START, NULL, 0, NULL, 0);
1222
	}
1223
1224
	DBGLOG(KERN_INFO "INFO\t[%s()]: done (fd = %d).", __func__, fd);
1225
	return rv;
1226
}
1227
1228
static void rdpuart_shutdown(struct rdpuart_port * port) {
1229
1230
	might_sleep();
1231
1232
	DBGLOG(KERN_INFO "INFO\t[rdpuart_shutdown()]: called");
1233
1234
	if (g_already_opened == 1) {
1235
	  g_stop = 1;
1236
	  cmd_exec(port, RDPUART_STOP, NULL, 0, NULL, 0);
1237
	}
1238
1239
	cmd_exec(port, RDPUART_CLOSE, NULL, 0, NULL, 0);
1240
	g_already_opened--;
1241
}
1242
1243
static void rdpuart_set_termios(struct rdpuart_port * port, struct ktermios * termios, struct ktermios * old) {
1244
	unsigned long flags = 0;
1245
	unsigned int baud = 0;
1246
1247
	DBGLOG(KERN_INFO "INFO\t[rdpuart_set_termios()]: called");
1248
1249
	spin_lock_irqsave(&(port->port.lock), flags);
1250
1251
	port->port.read_status_mask = RDPUART_STATUS_RXVALID | RDPUART_STATUS_OVERRUN
1252
		| RDPUART_STATUS_TXFULL;
1253
1254
	if (termios->c_iflag & INPCK) {
1255
	  port->port.read_status_mask |=
1256
		RDPUART_STATUS_PARITY | RDPUART_STATUS_FRAME;
1257
	}
1258
1259
	port->port.ignore_status_mask = 0;
1260
	if (termios->c_iflag & IGNPAR) {
1261
	  port->port.ignore_status_mask |= RDPUART_STATUS_PARITY
1262
		| RDPUART_STATUS_FRAME | RDPUART_STATUS_OVERRUN;
1263
	}
1264
1265
	/* ignore all characters if CREAD is not set */
1266
	if ((termios->c_cflag & CREAD) == 0) {
1267
	  port->port.ignore_status_mask |=
1268
		RDPUART_STATUS_RXVALID | RDPUART_STATUS_PARITY
1269
		| RDPUART_STATUS_FRAME | RDPUART_STATUS_OVERRUN;
1270
	}
1271
1272
	/* update timeout */
1273
	baud = uart_get_baud_rate(&(port->port), termios, old, 0, 460800);
1274
	uart_update_timeout(&(port->port), termios->c_cflag, baud);
1275
1276
	spin_unlock_irqrestore(&(port->port.lock), flags);
1277
}
1278
1279
static const char * rdpuart_type(struct rdpuart_port * port) {
1280
	const char * rv = title;
1281
1282
	DBGLOG(KERN_INFO "INFO\t[rdpuart_type()]: called");
1283
1284
	return (port->port.type == PORT_RDP) ? rv : NULL;
1285
}
1286
1287
static void rdpuart_release_port(struct rdpuart_port * port) {
1288
1289
	DBGLOG(KERN_INFO "INFO\t[rdpuart_release_port()]: called");
1290
1291
	port->port.membase = NULL;
1292
}
1293
1294
static int rdpuart_request_port(struct rdpuart_port * port) {
1295
	int rv = 0;
1296
1297
	DBGLOG(KERN_INFO "INFO\t[rdpuart_request_port()]: port=%p; port->mapbase=%llx", port, (unsigned long long) port->port.mapbase);
1298
1299
	port->port.membase = (void *)port->port.mapbase;
1300
1301
	return rv;
1302
}
1303
1304
static void rdpuart_config_port(struct rdpuart_port * port, int flags) {
1305
1306
	DBGLOG(KERN_INFO "INFO\t[rdpuart_config_port()]: called (flags = \"0x%8.8x\")", flags);
1307
1308
	if (!rdpuart_request_port(port)) {
1309
	  port->port.type = PORT_RDP;
1310
	}
1311
	port->port.flags = flags;
1312
}
1313
1314
static int rdpuart_verify_port(struct rdpuart_port * port, struct serial_struct * ser) {
1315
1316
	DBGLOG(KERN_INFO "INFO\t[rdpuart_verify_port()]: called");
1317
1318
	/* we don't want the core code to modify any port params */
1319
	//return -EINVAL;
1320
	return 0;
1321
}
1322
1323
static void rdpuart_send_xchar(struct rdpuart_port * port, char ch) {
1324
1325
	might_sleep();
1326
1327
	DBGLOG(KERN_INFO "INFO\t[rdpuart_send_xchar()]: called; ch = \"%c\" (%d)", ASCIICHR(ch), ch);
1328
1329
	cmd_exec(port, RDPUART_XCHAR, NULL, 0, NULL, 0);
1330
}
1331
1332
/*
1333
static int rdpuart_ioctl(struct rdpuart_port * port, unsigned int ioctl, unsigned long dp) {
1334
  int rv = 0;
1335
  void * rp = (void *)NULL;
1336
  void * iarg = (void *)NULL;
1337
  int rlen = 0;
1338
  int ilen = 0;
1339
  char * cname = (char *)NULL;
1340
1341
  switch (ioctl) {
1342
    case TCGETS:
1343
      {
1344
	struct termios * argp = (struct termios *)dp;
1345
	ilen = sizeof(struct termios);
1346
	iarg = (void *)argp;
1347
	cname = "TCGETS";
1348
      }
1349
      break;
1350
    case TCSETS:
1351
      {
1352
	const struct termios * argp = (const struct termios *)dp;
1353
	ilen = sizeof(struct termios);
1354
	iarg = (void *)argp;
1355
	cname = "TCSETS";
1356
      }
1357
      break;
1358
    case TCSETSW:
1359
      {
1360
	const struct termios * argp = (const struct termios *)dp;
1361
	ilen = sizeof(struct termios);
1362
	iarg = (void *)argp;
1363
	cname = "TCSETSW";
1364
      }
1365
      break;
1366
    case TCSETSF:
1367
      {
1368
	const struct termios * argp = (const struct termios *)dp;
1369
	ilen = sizeof(struct termios);
1370
	iarg = (void *)argp;
1371
	cname = "TCSETSF";
1372
      }
1373
      break;
1374
    case TCGETA:
1375
      {
1376
	struct termio * argp = (struct termio *)dp;
1377
	ilen = sizeof(struct termio);
1378
	iarg = (void *)argp;
1379
	cname = "TCGETA";
1380
      }
1381
      break;
1382
    case TCSETA:
1383
      {
1384
	const struct termio * argp = (const struct termio *)dp;
1385
	ilen = sizeof(struct termio);
1386
	iarg = (void *)argp;
1387
	cname = "TCSETA";
1388
      }
1389
      break;
1390
    case TCSETAW:
1391
      {
1392
	const struct termio * argp = (const struct termio *)dp;
1393
	ilen = sizeof(struct termio);
1394
	iarg = (void *)argp;
1395
	cname = "TCSETAW";
1396
      }
1397
      break;
1398
    case TCSETAF:
1399
      {
1400
	const struct termio * argp = (const struct termio *)dp;
1401
	ilen = sizeof(struct termio);
1402
	iarg = (void *)argp;
1403
	cname = "TCSETAF";
1404
      }
1405
      break;
1406
    case TIOCGLCKTRMIOS:
1407
      {
1408
	struct termios * argp = (struct termios *)dp;
1409
	ilen = sizeof(struct termios);
1410
	iarg = (void *)argp;
1411
	cname = "TIOCGLCKTRMIOS";
1412
      }
1413
      break;
1414
    case TIOCSLCKTRMIOS:
1415
      {
1416
	const struct termios * argp = (const struct termios *)dp;
1417
	ilen = sizeof(struct termios);
1418
	iarg = (void *)argp;
1419
	cname = "TIOCSLCKTRMIOS";
1420
      }
1421
      break;
1422
    case TIOCGWINSZ:
1423
      {
1424
	struct winsize * argp = (struct winsize *)dp;
1425
	ilen = sizeof(struct winsize);
1426
	iarg = (void *)argp;
1427
	cname = "TIOCGWINSZ";
1428
      }
1429
      break;
1430
    case TIOCSWINSZ:
1431
      {
1432
	const struct winsize * argp = (const struct winsize *)dp;
1433
	ilen = sizeof(struct winsize);
1434
	iarg = (void *)argp;
1435
	cname = "TIOCSWINSZ";
1436
      }
1437
      break;
1438
    case TCSBRK:
1439
      {
1440
	int arg = *((int *)dp);
1441
	ilen = sizeof(int);
1442
	iarg = (void *)&arg;
1443
	cname = "TCSBRK";
1444
      }
1445
      break;
1446
    case TCSBRKP:
1447
      {
1448
	int arg = *((int *)dp);
1449
	ilen = sizeof(int);
1450
	iarg = (void *)&arg;
1451
	cname = "TCSBRKP";
1452
      }
1453
      break;
1454
    case TIOCSBRK:
1455
      {
1456
	ilen = 0;
1457
	iarg = iarg;
1458
	cname = "TIOCSBRK";
1459
      }
1460
      break;
1461
    case TIOCCBRK:
1462
      {
1463
	ilen = 0;
1464
	iarg = iarg;
1465
	cname = "TIOCCBRK";
1466
      }
1467
      break;
1468
    case FIONREAD:
1469
      {
1470
	int * argp = (int *)dp;
1471
	ilen = sizeof(int *);
1472
	iarg = (void *)argp;
1473
	cname = "FIONREAD";
1474
      }
1475
      break;
1476
    case TIOCOUTQ:
1477
      {
1478
	int * argp = (int *)dp;
1479
	ilen = sizeof(int *);
1480
	iarg = (void *)argp;
1481
	cname = "TIOCOUTQ";
1482
      }
1483
      break;
1484
    case TCFLSH:
1485
      {
1486
	int arg = *((int *)dp);
1487
	ilen = sizeof(int);
1488
	iarg = (void *)&arg;
1489
	cname = "TCFLSH";
1490
      }
1491
      break;
1492
    case TIOCSTI:
1493
      {
1494
	const char * argp = (const char *)dp;
1495
	ilen = sizeof(char);
1496
	iarg = (void *)argp;
1497
	cname = "TIOCSTI";
1498
      }
1499
      break;
1500
    case TIOCCONS:
1501
      {
1502
	ilen = 0;
1503
	iarg = iarg;
1504
	cname = "TIOCCONS";
1505
      }
1506
      break;
1507
    case TIOCGETD:
1508
      {
1509
	int * argp = (int *)dp;
1510
	ilen = sizeof(int *);
1511
	iarg = (void *)argp;
1512
	cname = "TIOCGETD";
1513
      }
1514
      break;
1515
    case TIOCSETD:
1516
      {
1517
	const int * argp = (const int *)dp;
1518
	ilen = sizeof(int *);
1519
	iarg = (void *)argp;
1520
	cname = "TIOCSETD";
1521
      }
1522
      break;
1523
    case TIOCPKT:
1524
      {
1525
	ilen = 0;
1526
	iarg = iarg;
1527
	rv = -ENOTTY;
1528
	cname = "TIOCPKT";
1529
      }
1530
      break;
1531
    default:
1532
      {
1533
	cname = "(none)";
1534
      }
1535
      break;
1536
  }
1537
1538
  DBGLOG(KERN_INFO "INFO\t[rdpuart_ioctl()]: called (cmd = \"%s\")", cname);
1539
1540
  ilen = ilen;
1541
  rlen = rlen;
1542
  rp = rp;
1543
1544
  return rv;
1545
}
1546
1547
*/
1548
1549
static const rdpuart_ops_t l_rdpuart_ops = {
1550
	.tx_empty	= rdpuart_tx_empty,
1551
	.set_mctrl	= rdpuart_set_mctrl,
1552
	.get_mctrl	= rdpuart_get_mctrl,
1553
	.stop_tx	= rdpuart_stop_tx,
1554
	.start_tx	= rdpuart_start_tx,
1555
	.send_xchar	= rdpuart_send_xchar,
1556
	.stop_rx	= rdpuart_stop_rx,
1557
	.enable_ms	= rdpuart_enable_ms,
1558
	.break_ctl	= rdpuart_break_ctl,
1559
	.startup	= rdpuart_startup,
1560
	.shutdown	= rdpuart_shutdown,
1561
	.set_termios	= rdpuart_set_termios,
1562
	.type		= rdpuart_type,
1563
	.release_port	= rdpuart_release_port,
1564
//	.request_port	= rdpuart_request_port,
1565
	.config_port	= rdpuart_config_port,
1566
	.verify_port	= rdpuart_verify_port,
1567
//	.ioctl		= rdpuart_ioctl,
1568
};
1569
1570
static const struct uart_ops * rdpuart_ops = (const struct uart_ops *)&l_rdpuart_ops;
1571
1572
static struct uart_driver rdpuart_uart_driver = {
1573
	.owner		= THIS_MODULE,
1574
	.driver_name	= RDPUART_TITLE,
1575
	.dev_name	= RDPUART_NAME,
1576
	.major		= RDPUART_MAJOR,
1577
	.minor		= RDPUART_MINOR,
1578
	.nr		= RDPUART_NR_UARTS,
1579
};
1580
1581
/* ---------------------------------------------------------------------
1582
 * Port assignment functions (mapping devices to uart_port structures)
1583
 */
1584
1585
/** rdpuart_assign: register a rdpuart device with the driver
1586
 *
1587
 * @dev: pointer to device structure
1588
 * @id: requested id number.  Pass -1 for automatic port assignment
1589
 * @base: base address of rdpuart registers
1590
 * @irq: irq number for rdpuart
1591
 * @device_id: unique identifier for this port, provided by the RDP client
1592
 *
1593
 * Returns: 0 on success, < 0 otherwise
1594
 */
1595
static int __devinit rdpuart_assign(struct device * dev, int id, resource_size_t base, resource_size_t irq, uint32_t device_id) {
1596
	int rv = 0;
1597
	struct rdpuart_port * up = (struct rdpuart_port *)NULL;
1598
	struct uart_port * port = (struct uart_port *)NULL;
1599
	struct rdpuart_record * rec = (struct rdpuart_record *)NULL;
1600
	struct device * odev = dev;
1601
1602
	/* if id = -1; then scan for a free id and use that */
1603
	if (id < 0) {
1604
	  for (id = 0; id < nr; id++) {
1605
	    if (rdpuart_ports[id].port.mapbase == 0) {
1606
	      break;
1607
	    }
1608
	  }
1609
	}
1610
	if (id >= nr) {
1611
	  dev_err(dev, "%s%i too large", name, id);
1612
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_assign()]: \"%s%i\" exceeds the maximum number of UARTs for this device (RDPUART_NR_UARTS = \"%d\")", name, id, nr);
1613
	  return -EINVAL;
1614
	}
1615
	if (id < 0) {
1616
	  dev_err(dev, "\"%s\": invalid id (%i)", name, id);
1617
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_assign()]: invalid port id \"%i\"", id);
1618
	  return -EINVAL;
1619
	}
1620
	if ((rdpuart_ports[id].port.mapbase) && (rdpuart_ports[id].port.mapbase != base)) {
1621
	  dev_err(dev, "cannot assign to %s%i; it is already in use",	name, id);
1622
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_assign()]: cannot assign to \"%s%i\" (already in use)", name, id);
1623
	  return -EBUSY;
1624
	}
1625
1626
	up = &(rdpuart_ports[id]);
1627
	memset((up->cmd_array), 0, sizeof(up->cmd_array));
1628
	spin_lock_init(&(up->cmd_lock));
1629
1630
	port = &(rdpuart_ports[id].port);
1631
	g_port = port;
1632
1633
	up->device_id = device_id;
1634
1635
	spin_lock_init(&(port->lock));
1636
	//port->fifosize = 16;
1637
	port->regshift = 2;
1638
	port->iotype = UPIO_MEM;
1639
	port->iobase = 1; /* mark port as being in use */
1640
	port->mapbase = base;
1641
	port->membase = NULL;
1642
	port->ops = rdpuart_ops;
1643
	port->irq = irq;
1644
	port->dev = dev;
1645
	//port->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
1646
	//port->type = PORT_UNKNOWN;
1647
	port->type = PORT_RDPUART;
1648
	port->line = id;
1649
	port->uartclk = 9600 * 16;
1650
1651
	dev_set_drvdata(dev, port);
1652
1653
	/* Register the port */
1654
	DBGLOG(KERN_INFO "INFO\t[%s()]: about to call uart_add_one_port()...", __func__);
1655
	rv = uart_add_one_port(&rdpuart_uart_driver, port);
1656
	if (rv) {
1657
	  dev_err(dev, "ERROR\t[rdpuart_assign()]: uart_add_one_port() failed; (err=\"%i\")", rv);
1658
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_assign()]: uart_add_one_port() failed (err=\"%i\")", rv);
1659
	  port->mapbase = 0;
1660
	  dev_set_drvdata(dev, NULL);
1661
	}
1662
	else {
1663
	  rec = &(rdpuart_ports[id].rec);
1664
	  memset(rec, 0, sizeof(struct rdpuart_record));
1665
	  spin_lock_init(&(rec->lock));
1666
	  rec->owner = THIS_MODULE;
1667
	  rec->id = id;
1668
	  rec->initialized = 1;
1669
	  memcpy(&(rec->dev), odev, sizeof(struct device));
1670
	  rec->driver = rec->dev.driver;
1671
	  rec->seq = 1;
1672
	  snprintf(rec->name, (RDPUART_MAXNAMELEN - 1), "%s%d", title, rec->id);
1673
	  rec->port = port;
1674
	}
1675
1676
	return rv;
1677
}
1678
1679
/** rdpuart_release: unregister a rdpuart device from a driver
1680
 *
1681
 * @dev: pointer to device structure
1682
 */
1683
static int __devexit rdpuart_release(struct device * dev) {
1684
  int rc = 0;
1685
  struct rdpuart_port * port = (struct rdpuart_port *)NULL;
1686
  port = (struct rdpuart_port *)(dev_get_drvdata(dev));
1687
  if (port) {
1688
    rc = uart_remove_one_port(&rdpuart_uart_driver, &(port->port));
1689
    dev_set_drvdata(dev, NULL);
1690
    port->port.mapbase = 0;
1691
  }
1692
  return rc;
1693
}
1694
1695
/* ---------------------------------------------------------------------
1696
 * Platform bus binding
1697
 */
1698
1699
static int __devinit rdpuart_probe(struct platform_device * pdev) {
1700
	int rv = 0;
1701
	struct resource * mem = (struct resource *)NULL;
1702
	struct resource * irq = (struct resource *)NULL;
1703
1704
	if (pdev != NULL && pdev->name != NULL) {
1705
	  DBGLOG(KERN_INFO "INFO\t[rdpuart_probe()]: called (pdev->name = \"%s\")", pdev->name);
1706
	}
1707
1708
	if (pdev == NULL) {
1709
	  rv = -EINVAL;
1710
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_probe()]: pdev is a null pointer");
1711
	  goto end;
1712
	}
1713
	else if (!(mem = platform_get_resource(pdev, IORESOURCE_MEM, 0))) {
1714
	  rv = -ENODEV;
1715
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_probe()]: failed to assign iomem");
1716
	  goto end;
1717
	}
1718
	else if (!(irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0))) {
1719
	  rv = -ENODEV;
1720
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_probe()]: failed to assign irq");
1721
	  goto end;
1722
	}
1723
	else if ((rv = rdpuart_assign(&(pdev->dev), pdev->id, mem->start, irq->start, 0)) < 0) {
1724
	  DBGLOG(KERN_ERR "ERROR\t[rdpuart_probe()]: rdpuart_assign() returned error code \"%d\"", rv);
1725
	}
1726
1727
  end:
1728
	DBGLOG(KERN_INFO "INFO\t[rdpuart_probe()]: done.");
1729
	return rv;
1730
}
1731
1732
static int __devexit rdpuart_remove(struct platform_device * pdev) {
1733
	return rdpuart_release(&(pdev->dev));
1734
}
1735
1736
1737
/* ---------------------------------------------------------------------
1738
 *  RDP command work queue handler
1739
 */
1740
static void rdpuart_cmdw_handler(struct work_struct * work) {
1741
  if (g_exit == 0) {
1742
    cmd_process_list(&rdpuart_outbound_cmd_list);
1743
  }
1744
}
1745
1746
1747
/* ---------------------------------------------------------------------
1748
 * Module setup/teardown
1749
 */
1750
int __init rdpuart_init(void) {
1751
	int ret = 0;
1752
1753
	struct resource * iomem = (struct resource *)NULL;
1754
	struct resource * irq = (struct resource *)NULL;
1755
	struct resource rarr[2];
1756
1757
	rdpuart_platform_driver.driver.name	= title;
1758
	rdpuart_uart_driver.driver_name		= title;
1759
	rdpuart_uart_driver.dev_name		= name;
1760
	rdpuart_uart_driver.major		= major;
1761
	rdpuart_uart_driver.minor		= minor;
1762
	rdpuart_uart_driver.nr			= nr;
1763
1764
	memset(rdpuart_ports, 0, sizeof(rdpuart_ports));
1765
	memset(rarr,0,sizeof(struct resource)*2);
1766
	if (rarr == NULL) {
1767
	  ret = -ENOMEM;
1768
	  goto err_uart;
1769
	}
1770
	else {
1771
	  resource_size_t start = 0;
1772
	  resource_size_t end = 0;
1773
	  void * membuf = (void *)NULL;
1774
#if PAGE_SIZE > 3999
1775
	  membuf = (void *)get_zeroed_page(GFP_KERNEL);
1776
	  start = (resource_size_t)membuf;
1777
	  end = (resource_size_t)(membuf + PAGE_SIZE);
1778
#else
1779
	  membuf = kzalloc(4000, GFP_KERNEL);
1780
	  start = (resource_size_t)membuf;
1781
	  end = (resource_size_t)(membuf + 4000);
1782
#endif
1783
	  {
1784
	    struct resource liomem = {
1785
	      .start = start,
1786
	      .end = end,
1787
	      .flags = IORESOURCE_MEM,
1788
	    };
1789
	    struct resource lirq = {
1790
	      .start = (resource_size_t)RDPUART_NR_IRQ,
1791
	      .end = (resource_size_t)RDPUART_NR_IRQ,
1792
	      .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
1793
	    };
1794
	    iomem = &(rarr[0]);
1795
	    irq = &(rarr[1]);
1796
	    memcpy(iomem,&liomem,sizeof(struct resource));
1797
	    memcpy(irq,&lirq,sizeof(struct resource));
1798
	  }
1799
	}
1800
1801
	g_cmdq = create_singlethread_workqueue(Q_NAME);
1802
	//queue_delayed_work(g_cmdq, &g_cmdw, 100);
1803
1804
	DBGLOG(KERN_INFO "INFO\t[rdpuart_init()]: calling uart_register_driver()");
1805
	if ((ret = uart_register_driver(&rdpuart_uart_driver))) {
1806
	  goto err_uart;
1807
	}
1808
1809
	DBGLOG(KERN_INFO "INFO\t[rdpuart_init()]: calling platform_driver_register() {rdpuart_platform_driver.driver.bus = \"%p\"}",rdpuart_platform_driver.driver.bus);
1810
	if ((ret = platform_driver_register(&rdpuart_platform_driver))) {
1811
	  goto err_plat;
1812
	}
1813
1814
	if (1==2)
1815
	{
1816
	  struct resource * tarr = (struct resource *)NULL;
1817
	  DBGLOG(KERN_INFO "INFO\t[rdpuart_init()]: calling platform_device_register_simple() {rdpuart_platform_driver.driver.bus = \"%p\"}",rdpuart_platform_driver.driver.bus);
1818
	  tarr = (struct resource *)kzalloc(sizeof(rarr), GFP_KERNEL);
1819
	  memcpy(tarr,rarr,sizeof(rarr));
1820
	  if (!(gdev = platform_device_register_simple(title, -1, tarr, ARRAY_SIZE(rarr)))) {
1821
	    ret = -ENODEV;
1822
	    goto err_plat;
1823
	  }
1824
	}
1825
1826
	rdpuart_init_netlink();
1827
1828
	return ret;
1829
1830
err_plat:
1831
	uart_unregister_driver(&rdpuart_uart_driver);
1832
err_uart:
1833
	DBGLOG(KERN_ERR "registering rdpuart driver failed: err=%d", ret);
1834
	return ret;
1835
}
1836
1837
void __exit rdpuart_exit(void) {
1838
	g_exit = 1;
1839
	flush_workqueue(g_cmdq);
1840
	cancel_delayed_work(&g_cmdw);
1841
	destroy_workqueue(g_cmdq);
1842
	rdpuart_stop_netlink();
1843
	if (gdev != NULL) {
1844
	  platform_device_unregister(gdev);
1845
	}
1846
	platform_driver_unregister(&rdpuart_platform_driver);
1847
	uart_unregister_driver(&rdpuart_uart_driver);
1848
}
1849
1850
module_init(rdpuart_init);
1851
module_exit(rdpuart_exit);
1852
1853
MODULE_AUTHOR("Ryan Rafferty <ryanaxp@gmail.com>");
1854
MODULE_DESCRIPTION("Virtual serial port driver for RDP");
1855
MODULE_LICENSE("GPL");
1856
1857
/* work with hotplug and coldplug */
1858
/* M ODULE_ALIAS(R DPUART_ALIAS); */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/include/linux/rdp.h (+448 lines)
Line 0    Link Here 
1
/*
2
 *
3
 */
4
5
#ifndef LINUX_RDP_H
6
#define LINUX_RDP_H
7
8
#include <asm/byteorder.h>
9
#include <asm/io.h>
10
#include <asm/uaccess.h>
11
12
#include <linux/tty.h>
13
#include <linux/tty_driver.h>
14
#include <linux/tty_flip.h>
15
#include <linux/circ_buf.h>
16
#include <linux/delay.h>
17
#include <linux/interrupt.h>
18
#include <linux/init.h>
19
#include <linux/list.h>
20
#include <linux/sched.h>
21
#include <linux/version.h>
22
#include <linux/spinlock.h>
23
#include <linux/completion.h>
24
#include <linux/skbuff.h>
25
#include <linux/netlink.h>
26
#include <linux/connector.h>
27
#include <linux/serial.h>
28
29
30
/*	#define	PORT_RDP		PORT_UNKNOWN		*/
31
/*	#define	PORT_RDP		PORT_16550A		*/
32
/*	#define	PORT_RDP		PORT_8250		*/
33
#define	PORT_RDP			PORT_UARTLITE
34
#define	RDP_MAXNAMELEN			32
35
36
#define	CN_IDX_RDP			CN_IDX_CIFS + 0x10
37
#define	CN_VAL_RDP			CN_VAL_CIFS + 0x10
38
#define RDP_FAMILY_DEFAULT		0
39
#define	RDP_NETLINK_MSG_MAXSIZE	12000
40
41
#define RDP_NETLINK_DRIVER_BASE		0x0000deef
42
#define RDP_NETLINK_CLIENT_BASE		0xfeed0000
43
44
#ifndef MINVAL
45
#define MINVAL(x,y) (((x) > (y)) ? (y) : (x))
46
#endif
47
48
#define ASCIICHR(x) (((x) > 31 && x < 127) ? x : 0x20)
49
#define DBGLOG(...) {                           \
50
        printk(__VA_ARGS__);                    \
51
        printk("\n");                           \
52
}
53
#define RDPCMD(x) (cmdarray[(x & 0x1f)])
54
55
#define RDP_MAGIC	0xabee
56
57
typedef struct _rdp_data {
58
		/*	Per-device data					*/
59
60
		/* 	The RDP device id for this			*/
61
		/*	redirected serial port:				*/
62
	uint32_t			device_id;
63
64
		/*	The file handle of the AF_NETLINK device	*/
65
		/*	for communicating with userspace:		*/
66
	int				netlink_fh;
67
68
} rdp_data;
69
70
enum rdp_netlink_message_types {
71
	RDP_PING = 0x00,
72
	RDP_IOCTL = 0x01,
73
	RDP_SETMCTRL = 0x02,
74
	RDP_GETMCTRL = 0x03,
75
	RDP_GETSTATUS = 0x04,
76
	RDP_ADDPORT = 0x05,
77
	RDP_OPEN = 0x06,
78
	RDP_CLOSE = 0x07,
79
	RDP_READ = 0x08,
80
	RDP_WRITE = 0x09,
81
	RDP_DATA = 0x0A,
82
	RDP_START = 0x0B,
83
	RDP_STOP = 0x0C,
84
	RDP_GETBAUD = 0x0D,
85
	RDP_SETBAUD = 0x0E,
86
	RDP_TXEMPTY = 0x0F,
87
	RDP_TXFULL = 0x10,
88
	RDP_TXSTOP = 0x11,
89
	RDP_TXSTART = 0x12,
90
	RDP_RXEMPTY = 0x13,
91
	RDP_RXFULL = 0x14,
92
	RDP_RXSTOP = 0x15,
93
	RDP_RXSTART = 0x16,
94
	RDP_MSENABLE = 0x17,
95
	RDP_BREAKCTL = 0x18,
96
	RDP_SETTERMIOS = 0x19,
97
	RDP_GETTERMIOS = 0x1A,
98
	RDP_XCHAR = 0x1B,
99
	RDP_ASYNC = 0x40,
100
	RDP_REPLY = 0x80,
101
};
102
103
#define CMD_TO_STRING_ARRAY_DEF { \
104
        [0x00] = "RDP_PING", \
105
	[0x01] = "RDP_IOCTL", \
106
        [0x02] = "RDP_SETMCTRL", \
107
        [0x03] = "RDP_GETMCTRL", \
108
        [0x04] = "RDP_GETSTATUS", \
109
        [0x05] = "RDP_ADDPORT", \
110
        [0x06] = "RDP_OPEN", \
111
        [0x07] = "RDP_CLOSE", \
112
        [0x08] = "RDP_READ", \
113
        [0x09] = "RDP_WRITE", \
114
        [0x0A] = "RDP_DATA", \
115
        [0x0B] = "RDP_START", \
116
        [0x0C] = "RDP_STOP", \
117
        [0x0D] = "RDP_GETBAUD", \
118
        [0x0E] = "RDP_SETBAUD", \
119
	[0x0F] = "RDP_TXEMPTY", \
120
        [0x10] = "RDP_TXFULL", \
121
        [0x11] = "RDP_TXSTOP", \
122
        [0x12] = "RDP_TXSTART", \
123
        [0x13] = "RDP_RXEMPTY", \
124
        [0x14] = "RDP_RXFULL", \
125
        [0x15] = "RDP_RXSTOP", \
126
        [0x16] = "RDP_RXSTART", \
127
        [0x17] = "RDP_MSENABLE", \
128
        [0x18] = "RDP_BREAKCTL", \
129
	[0x19] = "RDP_SETTERMIOS", \
130
	[0x1A] = "RDP_GETTERMIOS", \
131
	[0x1B] = "RDP_XCHAR", \
132
        [0x40] = "RDP_ASYNC", \
133
        [0x80] = "RDP_REPLY", \
134
}
135
136
typedef struct rdp_irq_data {
137
	uint32_t		device_id;
138
	uint32_t		mask;
139
	uint8_t			dtr;
140
	uint8_t			rts;
141
	uint8_t			cd;
142
	uint8_t			ri;
143
	uint32_t		mcr;
144
	uint32_t		msr;
145
	uint32_t		status;
146
	uint32_t		rx_len;
147
	uint8_t			rx_buf[0];
148
} rdp_irq_data_t;
149
150
typedef struct rdp_irq_entry {
151
	struct rdp_port *	port;
152
	struct rdp_irq_data *	data;
153
	struct list_head	list;
154
} rdp_irq_entry_t;
155
156
typedef struct rdp_write_entry {
157
	struct rdp_port *	port;
158
	struct list_head	list;
159
	spinlock_t		lock;
160
	struct completion	done;
161
	unsigned char		completed;
162
	unsigned char		canceled;
163
	int			rv;
164
	int			len;
165
	unsigned char *		data;
166
} rdp_write_entry_t;
167
168
#ifndef __KERNEL__
169
170
typedef struct _rdp_netlink_msg {
171
	uint8_t					type;
172
	uint8_t					reserved;
173
	uint16_t				len;
174
	union {
175
	  uint8_t		id[8];
176
	  struct rdp_mst {
177
		uint32_t   id;
178
		uint32_t   res;
179
	  }                     mst;
180
	}					id;
181
	uint8_t					data[0];
182
} rdp_netlink_msg;
183
184
185
typedef struct _rdp_reg_num {
186
#if defined(__LITTLE_ENDIAN_BITFIELD)
187
	uint64_t	family:8;
188
	uint64_t       	id:48;
189
	uint64_t	crc:8;
190
#elif defined(__BIG_ENDIAN_BITFIELD)
191
	uint64_t	crc:8;
192
	uint64_t	id:48;
193
	uint64_t	family:8;
194
#else
195
#error "Please fix <asm/byteorder.h>"
196
#endif
197
} rdp_reg_num;
198
199
#endif
200
201
#ifdef __KERNEL__
202
203
#include <linux/completion.h>
204
#include <linux/device.h>
205
#include <linux/semaphore.h>
206
#include <linux/tty.h>
207
#include <linux/tty_driver.h>
208
#include <linux/tty_flip.h>
209
#include <linux/serial.h>
210
211
212
typedef struct _rdp_reg_num {
213
#if defined(__LITTLE_ENDIAN_BITFIELD)
214
	__u64   family:8,
215
	        id:48,
216
	        crc:8;
217
#elif defined(__BIG_ENDIAN_BITFIELD)
218
	__u64   crc:8,
219
	        id:48,
220
	        family:8;
221
#else
222
#error "Please fix <asm/byteorder.h>"
223
#endif
224
} rdp_reg_num;
225
226
227
/***
228
 ***	Netlink/Connection ("cn") definitions
229
 ***/
230
231
typedef struct rdp_record {
232
	struct rdp_port *		port;
233
	struct tty_struct *		tty;
234
	struct module *			owner;
235
	char				name[RDP_MAXNAMELEN];
236
	unsigned long			attempts;
237
	int				initialized;
238
	u32				id;
239
	int				search_count;
240
	atomic_t			refcnt;
241
	void *				priv;
242
	ssize_t				priv_size;
243
	long				flags;
244
	struct task_struct *		thread;
245
	struct semaphore		mutex;
246
	struct device_driver *		driver;
247
	struct device			dev;
248
	spinlock_t			lock;
249
	u32				seq;
250
	struct rdp_family *		family;
251
	void *				family_data;
252
	struct completion		released;
253
	struct list_head		list;
254
} rdp_record_t;
255
256
typedef struct _rdp_netlink_msg {
257
	__u8				type;
258
	__u8				reserved;
259
	__u16				len;
260
	union {
261
	  __u8			id[8];
262
	  struct rdp_mst {
263
		__u32	id;
264
		__u32	res;
265
	  }			mst;
266
	}				id;
267
	__u8				data[0];
268
} rdp_netlink_msg;
269
270
#ifndef __RDP_FAMILY_H
271
#define __RDP_FAMILY_H
272
273
#include <linux/types.h>
274
#include <linux/device.h>
275
#include <asm/atomic.h>
276
277
#define MAXNAMELEN			32
278
279
struct rdp_family_ops {
280
        int  (* op)(struct rdp_record *);
281
};
282
283
struct rdp_family {
284
	struct list_head        	family_entry;
285
	u8                      	fid;
286
287
	struct rdp_family_ops *		fops;
288
289
	atomic_t                	refcnt;
290
	u8                      	need_exit;
291
	spinlock_t			lock;
292
};
293
294
void rdp_family_get(struct rdp_family *);
295
void rdp_family_put(struct rdp_family *);
296
struct rdp_family * rdp_family_registered(u8);
297
void rdp_unregister_family(struct rdp_family *);
298
int rdp_register_family(struct rdp_family *);
299
300
#endif /* __RDP_FAMILY_H */
301
302
303
typedef struct rdp_tty {
304
	struct tty_driver *	driver;
305
	struct list_head	list;
306
	#define	RDP_STATUS_NORMAL		0x00
307
	#define	RDP_STATUS_EXIT			0x01
308
	#define RDP_STATUS_LOADING		0x02
309
	#define RDP_STATUS_CLOSING		0x04
310
	#define RDP_STATUS_ERROR		0x08
311
	atomic_t		status;
312
	//unsigned char		status;
313
	struct mutex		mut;
314
} rdp_tty_t;
315
316
typedef struct rdp_cmd {
317
	unsigned char		cmd;
318
	void *			idata;
319
	int			ilen;
320
	void *			odata;
321
	int			olen;
322
323
	spinlock_t		lock;
324
	int			seqid;
325
	atomic_t		completed;
326
	struct list_head	list;
327
328
	struct rdp_record *	rec;
329
	struct rdp_port *	port;
330
	struct tty_struct *	tty;
331
332
	int			cmd_idx;
333
	struct completion *	done;
334
335
	void *			aux;
336
} rdp_cmd_t;
337
338
339
typedef struct completed_cmd_list {
340
	struct rdp_cmd *        cmd;
341
	struct list_head        list;
342
} completed_cmd_list_t;
343
344
345
typedef struct rdp_port {
346
	#define MAX_PORT	4
347
	#define	CMD_MAX		32
348
	#define CMD_OFFSET	4
349
	struct tty_port		port;
350
	struct rdp_record	rec;
351
	struct tty_struct *	tty;
352
	struct list_head	list;
353
	unsigned char		initialized;
354
	int			g_ports_index;
355
	atomic_t		open_count;
356
	uint32_t		device_id;
357
	spinlock_t		cmd_lock;
358
	int			cmd_array[CMD_MAX];
359
	spinlock_t		status_lock;
360
	struct mutex		mut;
361
	struct file *		fp;
362
	int			msr;            /* MSR shadow */
363
	int			mcr;            /* MCR shadow */
364
	int			flags;		/* defined in tty.h */
365
	int			baud;
366
	int			x_char;
367
	wait_queue_head_t	wait;
368
	struct async_icount	icount;
369
	struct circ_buf		xmit;
370
	int			blocked_open;
371
	wait_queue_head_t	open_wait;
372
	wait_queue_head_t	close_wait;
373
	struct serial_struct	serial;
374
} rdp_port_t;
375
376
377
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
378
#  define	CBARGS	struct cn_msg * imsg, struct netlink_skb_parms * parms
379
#else
380
#  define	CBARGS	void * imsg
381
#endif
382
383
typedef struct rdp_cb_entry {
384
	struct list_head		list;
385
	struct netlink_skb_parms	parms;
386
	struct cn_msg			imsg;
387
} rdp_cb_entry_t;
388
389
390
#endif	/* __KERNEL__			*/
391
392
#ifndef WIN32_SERIAL
393
394
#define  MAX_BAUD_RATE              460800
395
#define  MAX_BAUD_REMAINDER         4608
396
397
#define  DIV_LATCH_LS               0x00
398
#define  XMT_HOLD_REGISTER          0x00
399
#define  XVR_BUFFER_REGISTER        0x00
400
#define  DIV_LATCH_MS               0x01
401
#define  FIFO_CONTROL_REGISTER      0x02
402
#define  LINE_CONTROL_REGISTER      0x03
403
#define  MODEM_CONTROL_REGISTER     0x04
404
#define  LINE_STATUS_REGISTER       0x05
405
#define  MODEM_STATUS_REGISTER      0x06
406
407
#define  SERIAL_MCR_DTR             0x01
408
#define  SERIAL_MCR_RTS             0x02
409
#define  SERIAL_MCR_LOOP            0x10
410
411
#define  SERIAL_MSR_CTS             0x10
412
#define  SERIAL_MSR_CD              0x80
413
#define  SERIAL_MSR_RI              0x40
414
#define  SERIAL_MSR_DSR             0x20
415
#define  SERIAL_MSR_MASK            0xf0
416
417
#define  SERIAL_8_DATA              0x03
418
#define  SERIAL_7_DATA              0x02
419
#define  SERIAL_6_DATA              0x01
420
#define  SERIAL_5_DATA              0x00
421
422
#define  SERIAL_ODD_PARITY          0X08
423
#define  SERIAL_EVEN_PARITY         0X18
424
#define  SERIAL_TWO_STOPB           0x04
425
#define  SERIAL_ONE_STOPB           0x00
426
427
#define DEFAULT_DIVISOR  0x30	/* gives 9600 baud rate */
428
#define DEFAULT_LCR SERIAL_8_DATA	/* 8, none , 1 */
429
430
#define SERIAL_LSR_OE       0x02
431
#define SERIAL_LSR_PE       0x04
432
#define SERIAL_LSR_FE       0x08
433
#define SERIAL_LSR_BI       0x10
434
435
#define  SERIAL_MSR_CTS             0x10
436
#define  SERIAL_MSR_CD              0x80
437
#define  SERIAL_MSR_RI              0x40
438
#define  SERIAL_MSR_DSR             0x20
439
#define  SERIAL_MSR_MASK            0xf0
440
441
#define LOOPMODE_BITS       0x41	/* LOOP1 = b6, LOOP0 = b0 (PORT B) */
442
#define ALL_LOOPBACK        0x01
443
#define MODEM_CTRL          0x40
444
#define RS232_MODE          0x00
445
446
#endif
447
448
#endif	/* LINUX_RDP_H		*/
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/include/linux/rdptty.h (+327 lines)
Line 0    Link Here 
1
/*
2
 *
3
 */
4
5
#ifndef LINUX_RDPTTY_H
6
#define LINUX_RDPTTY_H
7
8
#include <asm/byteorder.h>
9
10
/*	#define	PORT_RDP		PORT_UNKNOWN		*/
11
/*	#define	PORT_RDP		PORT_16550A		*/
12
/*	#define	PORT_RDP		PORT_8250		*/
13
#define	PORT_RDP			PORT_UARTLITE
14
#define PORT_RDPTTY			PORT_RDP
15
#define	RDPTTY_MAXNAMELEN		32
16
17
#define	CN_IDX_RDPTTY			CN_IDX_CIFS + 0x10
18
#define	CN_VAL_RDPTTY			CN_VAL_CIFS + 0x10
19
#define RDPTTY_FAMILY_DEFAULT		0
20
#define	RDPTTY_NETLINK_MSG_MAXSIZE	12000
21
22
typedef struct _rdptty_data {
23
		/*	Per-device data					*/
24
25
		/* 	The RDP device id for this			*/
26
		/*	redirected serial port:				*/
27
	uint32_t			device_id;
28
29
		/*	The file handle of the AF_NETLINK device	*/
30
		/*	for communicating with userspace:		*/
31
	int				netlink_fh;
32
33
} rdptty_data;
34
35
enum rdptty_netlink_message_types {
36
	RDPTTY_PING = 0x00,
37
	RDPTTY_IOCTL = 0x01,
38
	RDPTTY_SETMCTRL = 0x02,
39
	RDPTTY_GETMCTRL = 0x03,
40
	RDPTTY_GETSTATUS = 0x04,
41
	RDPTTY_ADDPORT = 0x05,
42
	RDPTTY_OPEN = 0x06,
43
	RDPTTY_CLOSE = 0x07,
44
	RDPTTY_READ = 0x08,
45
	RDPTTY_WRITE = 0x09,
46
	RDPTTY_DATA = 0x0A,
47
	RDPTTY_START = 0x0B,
48
	RDPTTY_STOP = 0x0C,
49
	RDPTTY_GETBAUD = 0x0D,
50
	RDPTTY_SETBAUD = 0x0E,
51
	RDPTTY_TXEMPTY = 0x0F,
52
	RDPTTY_TXFULL = 0x10,
53
	RDPTTY_TXSTOP = 0x11,
54
	RDPTTY_TXSTART = 0x12,
55
	RDPTTY_RXEMPTY = 0x13,
56
	RDPTTY_RXFULL = 0x14,
57
	RDPTTY_RXSTOP = 0x15,
58
	RDPTTY_RXSTART = 0x16,
59
	RDPTTY_MSENABLE = 0x17,
60
	RDPTTY_BREAKCTL = 0x18,
61
	RDPTTY_SETTERMIOS = 0x19,
62
	RDPTTY_GETTERMIOS = 0x1A,
63
	RDPTTY_XCHAR = 0x1B,
64
	RDPTTY_ASYNC = 0x40,
65
	RDPTTY_REPLY = 0x80,
66
};
67
68
#define CMD_TO_STRING_ARRAY_DEF { \
69
        [0x00] = "RDPTTY_PING", \
70
	[0x01] = "RDPTTY_IOCTL", \
71
        [0x02] = "RDPTTY_SETMCTRL", \
72
        [0x03] = "RDPTTY_GETMCTRL", \
73
        [0x04] = "RDPTTY_GETSTATUS", \
74
        [0x05] = "RDPTTY_ADDPORT", \
75
        [0x06] = "RDPTTY_OPEN", \
76
        [0x07] = "RDPTTY_CLOSE", \
77
        [0x08] = "RDPTTY_READ", \
78
        [0x09] = "RDPTTY_WRITE", \
79
        [0x0A] = "RDPTTY_DATA", \
80
        [0x0B] = "RDPTTY_START", \
81
        [0x0C] = "RDPTTY_STOP", \
82
        [0x0D] = "RDPTTY_GETBAUD", \
83
        [0x0E] = "RDPTTY_SETBAUD", \
84
	[0x0F] = "RDPTTY_TXEMPTY", \
85
        [0x10] = "RDPTTY_TXFULL", \
86
        [0x11] = "RDPTTY_TXSTOP", \
87
        [0x12] = "RDPTTY_TXSTART", \
88
        [0x13] = "RDPTTY_RXEMPTY", \
89
        [0x14] = "RDPTTY_RXFULL", \
90
        [0x15] = "RDPTTY_RXSTOP", \
91
        [0x16] = "RDPTTY_RXSTART", \
92
        [0x17] = "RDPTTY_MSENABLE", \
93
        [0x18] = "RDPTTY_BREAKCTL", \
94
	[0x19] = "RDPTTY_SETTERMIOS", \
95
	[0x1A] = "RDPTTY_GETTERMIOS", \
96
	[0x1B] = "RDPTTY_XCHAR", \
97
        [0x40] = "RDPTTY_ASYNC", \
98
        [0x80] = "RDPTTY_REPLY", \
99
}
100
101
typedef struct rdptty_irq_data {
102
	uint32_t		device_id;
103
	uint32_t		mask;
104
	uint8_t			dtr;
105
	uint8_t			rts;
106
	uint8_t			cd;
107
	uint8_t			ri;
108
	uint32_t		mcr;
109
	uint32_t		msr;
110
	uint32_t		status;
111
	uint32_t		rx_len;
112
	uint8_t			rx_buf[0];
113
} rdptty_irq_data_t;
114
115
#ifndef __KERNEL__
116
117
typedef struct _rdptty_netlink_msg {
118
	uint8_t					type;
119
	uint8_t					reserved;
120
	uint16_t				len;
121
	union {
122
	  uint8_t		id[8];
123
	  struct rdptty_mst {
124
		uint32_t   id;
125
		uint32_t   res;
126
	  }                     mst;
127
	}					id;
128
	uint8_t					data[0];
129
} rdptty_netlink_msg;
130
131
132
typedef struct _rdptty_reg_num {
133
#if defined(__LITTLE_ENDIAN_BITFIELD)
134
	uint64_t	family:8;
135
	uint64_t       	id:48;
136
	uint64_t	crc:8;
137
#elif defined(__BIG_ENDIAN_BITFIELD)
138
	uint64_t	crc:8;
139
	uint64_t	id:48;
140
	uint64_t	family:8;
141
#else
142
#error "Please fix <asm/byteorder.h>"
143
#endif
144
} rdptty_reg_num;
145
146
#endif
147
148
#ifdef __KERNEL__
149
150
#include <linux/completion.h>
151
#include <linux/device.h>
152
#include <linux/semaphore.h>
153
154
typedef struct _rdptty_reg_num {
155
#if defined(__LITTLE_ENDIAN_BITFIELD)
156
	__u64   family:8,
157
	        id:48,
158
	        crc:8;
159
#elif defined(__BIG_ENDIAN_BITFIELD)
160
	__u64   crc:8,
161
	        id:48,
162
	        family:8;
163
#else
164
#error "Please fix <asm/byteorder.h>"
165
#endif
166
} rdptty_reg_num;
167
168
169
/***
170
 ***	Netlink/Connection ("cn") definitions
171
 ***/
172
173
typedef struct rdptty_record {
174
	struct tty_port *		port;
175
	struct rdptty_port *		rdp_port;
176
	struct module *			owner;
177
	unsigned char			name[RDPTTY_MAXNAMELEN];
178
	unsigned long			attempts;
179
	int				initialized;
180
	u32				id;
181
	int				search_count;
182
	atomic_t			refcnt;
183
	void *				priv;
184
	ssize_t				priv_size;
185
	long				flags;
186
	struct task_struct *		thread;
187
	struct semaphore		mutex;
188
	struct device_driver *		driver;
189
	struct device			dev;
190
	spinlock_t			lock;
191
	u32				seq;
192
	struct rdptty_family *		family;
193
	void *				family_data;
194
	struct completion		released;
195
	struct list_head		list;
196
} rdptty_record_t;
197
198
typedef struct _rdptty_netlink_msg {
199
	__u8				type;
200
	__u8				reserved;
201
	__u16				len;
202
	union {
203
	  __u8			id[8];
204
	  struct rdptty_mst {
205
		__u32	id;
206
		__u32	res;
207
	  }			mst;
208
	}				id;
209
	__u8				data[0];
210
} rdptty_netlink_msg;
211
212
typedef struct rdptty_port {
213
	#define	CMD_MAX			32
214
	#define	CMD_OFFSET		4
215
	struct tty_port			port;
216
	struct list_head		list;
217
	struct rdptty_record		rec;
218
	spinlock_t			cmd_lock;
219
	unsigned char			cmd_array[(CMD_MAX - CMD_OFFSET)];
220
	atomic_t			already_opened;
221
	uint32_t			device_id;
222
	unsigned char			in_use;
223
} rdptty_port_t;
224
225
int rdptty_netlink_send(struct rdptty_record *, rdptty_netlink_msg *, int);
226
int rdptty_init_netlink(void);
227
void rdptty_stop_netlink(void);
228
229
#ifndef __RDPTTY_FAMILY_H
230
#define __RDPTTY_FAMILY_H
231
232
#include <linux/types.h>
233
#include <linux/device.h>
234
#include <asm/atomic.h>
235
236
#define MAXNAMELEN			32
237
238
struct rdptty_family_ops {
239
        int  (* ping)(struct rdptty_record *);
240
        void (* pong)(struct rdptty_record *);
241
};
242
243
struct rdptty_family {
244
        struct list_head        	family_entry;
245
        u8                      	fid;
246
247
        struct rdptty_family_ops *	fops;
248
249
        atomic_t                	refcnt;
250
        u8                      	need_exit;
251
};
252
253
extern spinlock_t rdptty_flock;
254
255
void rdptty_family_get(struct rdptty_family *);
256
void rdptty_family_put(struct rdptty_family *);
257
void __rdptty_family_get(struct rdptty_family *);
258
void __rdptty_family_put(struct rdptty_family *);
259
struct rdptty_family * rdptty_family_registered(u8);
260
void rdptty_unregister_family(struct rdptty_family *);
261
int rdptty_register_family(struct rdptty_family *);
262
263
#endif /* __RDPTTY_FAMILY_H */
264
265
266
typedef struct tty_operations rdptty_ops_t;
267
268
269
#endif	/* __KERNEL__			*/
270
271
#ifndef WIN32_SERIAL
272
273
#define  MAX_BAUD_RATE              460800
274
#define  MAX_BAUD_REMAINDER         4608
275
276
#define  DIV_LATCH_LS               0x00
277
#define  XMT_HOLD_REGISTER          0x00
278
#define  XVR_BUFFER_REGISTER        0x00
279
#define  DIV_LATCH_MS               0x01
280
#define  FIFO_CONTROL_REGISTER      0x02
281
#define  LINE_CONTROL_REGISTER      0x03
282
#define  MODEM_CONTROL_REGISTER     0x04
283
#define  LINE_STATUS_REGISTER       0x05
284
#define  MODEM_STATUS_REGISTER      0x06
285
286
#define  SERIAL_MCR_DTR             0x01
287
#define  SERIAL_MCR_RTS             0x02
288
#define  SERIAL_MCR_LOOP            0x10
289
290
#define  SERIAL_MSR_CTS             0x10
291
#define  SERIAL_MSR_CD              0x80
292
#define  SERIAL_MSR_RI              0x40
293
#define  SERIAL_MSR_DSR             0x20
294
#define  SERIAL_MSR_MASK            0xf0
295
296
#define  SERIAL_8_DATA              0x03
297
#define  SERIAL_7_DATA              0x02
298
#define  SERIAL_6_DATA              0x01
299
#define  SERIAL_5_DATA              0x00
300
301
#define  SERIAL_ODD_PARITY          0X08
302
#define  SERIAL_EVEN_PARITY         0X18
303
#define  SERIAL_TWO_STOPB           0x04
304
#define  SERIAL_ONE_STOPB           0x00
305
306
#define DEFAULT_DIVISOR  0x30	/* gives 9600 baud rate */
307
#define DEFAULT_LCR SERIAL_8_DATA	/* 8, none , 1 */
308
309
#define SERIAL_LSR_OE       0x02
310
#define SERIAL_LSR_PE       0x04
311
#define SERIAL_LSR_FE       0x08
312
#define SERIAL_LSR_BI       0x10
313
314
#define  SERIAL_MSR_CTS             0x10
315
#define  SERIAL_MSR_CD              0x80
316
#define  SERIAL_MSR_RI              0x40
317
#define  SERIAL_MSR_DSR             0x20
318
#define  SERIAL_MSR_MASK            0xf0
319
320
#define LOOPMODE_BITS       0x41	/* LOOP1 = b6, LOOP0 = b0 (PORT B) */
321
#define ALL_LOOPBACK        0x01
322
#define MODEM_CTRL          0x40
323
#define RS232_MODE          0x00
324
325
#endif
326
327
#endif	/* LINUX_RDPTTY_H		*/
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/include/linux/rdpuart.h (+371 lines)
Line 0    Link Here 
1
/*
2
 *
3
 */
4
5
#ifndef LINUX_RDPUART_H
6
#define LINUX_RDPUART_H
7
8
#include <asm/byteorder.h>
9
10
/*	#define	PORT_RDP		PORT_UNKNOWN		*/
11
/*	#define	PORT_RDP		PORT_16550A		*/
12
/*	#define	PORT_RDP		PORT_8250		*/
13
#define	PORT_RDP			PORT_UARTLITE
14
#define PORT_RDPUART			PORT_RDP
15
#define	RDPUART_MAXNAMELEN		32
16
17
#define	CN_IDX_RDPUART			CN_IDX_CIFS + 0x10
18
#define	CN_VAL_RDPUART			CN_VAL_CIFS + 0x10
19
#define RDPUART_FAMILY_DEFAULT		0
20
#define	RDPUART_NETLINK_MSG_MAXSIZE	12000
21
22
typedef struct _rdpuart_data {
23
		/*	Per-device data					*/
24
25
		/* 	The RDP device id for this			*/
26
		/*	redirected serial port:				*/
27
	uint32_t			device_id;
28
29
		/*	The file handle of the AF_NETLINK device	*/
30
		/*	for communicating with userspace:		*/
31
	int				netlink_fh;
32
33
} rdpuart_data;
34
35
enum rdpuart_netlink_message_types {
36
	RDPUART_PING = 0x00,
37
	RDPUART_IOCTL = 0x01,
38
	RDPUART_SETMCTRL = 0x02,
39
	RDPUART_GETMCTRL = 0x03,
40
	RDPUART_GETSTATUS = 0x04,
41
	RDPUART_ADDPORT = 0x05,
42
	RDPUART_OPEN = 0x06,
43
	RDPUART_CLOSE = 0x07,
44
	RDPUART_READ = 0x08,
45
	RDPUART_WRITE = 0x09,
46
	RDPUART_DATA = 0x0A,
47
	RDPUART_START = 0x0B,
48
	RDPUART_STOP = 0x0C,
49
	RDPUART_GETBAUD = 0x0D,
50
	RDPUART_SETBAUD = 0x0E,
51
	RDPUART_TXEMPTY = 0x0F,
52
	RDPUART_TXFULL = 0x10,
53
	RDPUART_TXSTOP = 0x11,
54
	RDPUART_TXSTART = 0x12,
55
	RDPUART_RXEMPTY = 0x13,
56
	RDPUART_RXFULL = 0x14,
57
	RDPUART_RXSTOP = 0x15,
58
	RDPUART_RXSTART = 0x16,
59
	RDPUART_MSENABLE = 0x17,
60
	RDPUART_BREAKCTL = 0x18,
61
	RDPUART_SETTERMIOS = 0x19,
62
	RDPUART_GETTERMIOS = 0x1A,
63
	RDPUART_XCHAR = 0x1B,
64
	RDPUART_ASYNC = 0x40,
65
	RDPUART_REPLY = 0x80,
66
};
67
68
#define CMD_TO_STRING_ARRAY_DEF { \
69
        [0x00] = "RDPUART_PING", \
70
	[0x01] = "RDPUART_IOCTL", \
71
        [0x02] = "RDPUART_SETMCTRL", \
72
        [0x03] = "RDPUART_GETMCTRL", \
73
        [0x04] = "RDPUART_GETSTATUS", \
74
        [0x05] = "RDPUART_ADDPORT", \
75
        [0x06] = "RDPUART_OPEN", \
76
        [0x07] = "RDPUART_CLOSE", \
77
        [0x08] = "RDPUART_READ", \
78
        [0x09] = "RDPUART_WRITE", \
79
        [0x0A] = "RDPUART_DATA", \
80
        [0x0B] = "RDPUART_START", \
81
        [0x0C] = "RDPUART_STOP", \
82
        [0x0D] = "RDPUART_GETBAUD", \
83
        [0x0E] = "RDPUART_SETBAUD", \
84
	[0x0F] = "RDPUART_TXEMPTY", \
85
        [0x10] = "RDPUART_TXFULL", \
86
        [0x11] = "RDPUART_TXSTOP", \
87
        [0x12] = "RDPUART_TXSTART", \
88
        [0x13] = "RDPUART_RXEMPTY", \
89
        [0x14] = "RDPUART_RXFULL", \
90
        [0x15] = "RDPUART_RXSTOP", \
91
        [0x16] = "RDPUART_RXSTART", \
92
        [0x17] = "RDPUART_MSENABLE", \
93
        [0x18] = "RDPUART_BREAKCTL", \
94
	[0x19] = "RDPUART_SETTERMIOS", \
95
	[0x1A] = "RDPUART_GETTERMIOS", \
96
	[0x1B] = "RDPUART_XCHAR", \
97
        [0x40] = "RDPUART_ASYNC", \
98
        [0x80] = "RDPUART_REPLY", \
99
}
100
101
typedef struct rdpuart_irq_data {
102
	uint32_t		device_id;
103
	uint32_t		mask;
104
	uint8_t			dtr;
105
	uint8_t			rts;
106
	uint8_t			cd;
107
	uint8_t			ri;
108
	uint32_t		mcr;
109
	uint32_t		msr;
110
	uint32_t		status;
111
	uint32_t		rx_len;
112
	uint8_t			rx_buf[0];
113
} rdpuart_irq_data_t;
114
115
#ifndef __KERNEL__
116
117
typedef struct _rdpuart_netlink_msg {
118
	uint8_t					type;
119
	uint8_t					reserved;
120
	uint16_t				len;
121
	union {
122
	  uint8_t		id[8];
123
	  struct rdpuart_mst {
124
		uint32_t   id;
125
		uint32_t   res;
126
	  }                     mst;
127
	}					id;
128
	uint8_t					data[0];
129
} rdpuart_netlink_msg;
130
131
132
typedef struct _rdpuart_reg_num {
133
#if defined(__LITTLE_ENDIAN_BITFIELD)
134
	uint64_t	family:8;
135
	uint64_t       	id:48;
136
	uint64_t	crc:8;
137
#elif defined(__BIG_ENDIAN_BITFIELD)
138
	uint64_t	crc:8;
139
	uint64_t	id:48;
140
	uint64_t	family:8;
141
#else
142
#error "Please fix <asm/byteorder.h>"
143
#endif
144
} rdpuart_reg_num;
145
146
#endif
147
148
#ifdef __KERNEL__
149
150
#include <linux/completion.h>
151
#include <linux/device.h>
152
#include <linux/semaphore.h>
153
154
typedef struct _rdpuart_reg_num {
155
#if defined(__LITTLE_ENDIAN_BITFIELD)
156
	__u64   family:8,
157
	        id:48,
158
	        crc:8;
159
#elif defined(__BIG_ENDIAN_BITFIELD)
160
	__u64   crc:8,
161
	        id:48,
162
	        family:8;
163
#else
164
#error "Please fix <asm/byteorder.h>"
165
#endif
166
} rdpuart_reg_num;
167
168
169
/***
170
 ***	Netlink/Connection ("cn") definitions
171
 ***/
172
173
typedef struct rdpuart_record {
174
	struct uart_port *		port;
175
	struct rdpuart_port *		rdp_port;
176
	struct module *			owner;
177
	unsigned char			name[RDPUART_MAXNAMELEN];
178
	unsigned long			attempts;
179
	int				initialized;
180
	u32				id;
181
	int				search_count;
182
	atomic_t			refcnt;
183
	void *				priv;
184
	ssize_t				priv_size;
185
	long				flags;
186
	struct task_struct *		thread;
187
	struct semaphore		mutex;
188
	struct device_driver *		driver;
189
	struct device			dev;
190
	spinlock_t			lock;
191
	u32				seq;
192
	struct rdpuart_family *		family;
193
	void *				family_data;
194
	struct completion		released;
195
	struct list_head		list;
196
} rdpuart_record_t;
197
198
typedef struct _rdpuart_netlink_msg {
199
	__u8				type;
200
	__u8				reserved;
201
	__u16				len;
202
	union {
203
	  __u8			id[8];
204
	  struct rdpuart_mst {
205
		__u32	id;
206
		__u32	res;
207
	  }			mst;
208
	}				id;
209
	__u8				data[0];
210
} rdpuart_netlink_msg;
211
212
typedef struct rdpuart_port {
213
	#define	CMD_MAX			32
214
	#define	CMD_OFFSET		4
215
	struct uart_port		port;
216
	struct timer_list		timer;
217
	struct list_head		list;
218
	struct rdpuart_record		rec;
219
	spinlock_t			cmd_lock;
220
	unsigned char			cmd_array[(CMD_MAX - CMD_OFFSET)];
221
	atomic_t			already_opened;
222
	atomic_t			poll_scheduled;
223
	uint32_t			device_id;
224
} rdpuart_port_t;
225
226
int rdpuart_netlink_send(struct rdpuart_record *, rdpuart_netlink_msg *, int);
227
int rdpuart_init_netlink(void);
228
void rdpuart_stop_netlink(void);
229
230
#ifndef __RDPUART_FAMILY_H
231
#define __RDPUART_FAMILY_H
232
233
#include <linux/types.h>
234
#include <linux/device.h>
235
#include <asm/atomic.h>
236
237
#define MAXNAMELEN			32
238
239
struct rdpuart_family_ops {
240
        int  (* ping)(struct rdpuart_record *);
241
        void (* pong)(struct rdpuart_record *);
242
};
243
244
struct rdpuart_family {
245
        struct list_head        	family_entry;
246
        u8                      	fid;
247
248
        struct rdpuart_family_ops *	fops;
249
250
        atomic_t                	refcnt;
251
        u8                      	need_exit;
252
};
253
254
extern spinlock_t rdpuart_flock;
255
256
void rdpuart_family_get(struct rdpuart_family *);
257
void rdpuart_family_put(struct rdpuart_family *);
258
void __rdpuart_family_get(struct rdpuart_family *);
259
void __rdpuart_family_put(struct rdpuart_family *);
260
struct rdpuart_family * rdpuart_family_registered(u8);
261
void rdpuart_unregister_family(struct rdpuart_family *);
262
int rdpuart_register_family(struct rdpuart_family *);
263
264
#endif /* __RDPUART_FAMILY_H */
265
266
267
typedef struct rdpuart_opset {
268
	unsigned int	(*tx_empty)(struct rdpuart_port *);
269
	void		(*set_mctrl)(struct rdpuart_port *, unsigned int mctrl);
270
	unsigned int	(*get_mctrl)(struct rdpuart_port *);
271
	void		(*stop_tx)(struct rdpuart_port *);
272
	void		(*start_tx)(struct rdpuart_port *);
273
	void		(*send_xchar)(struct rdpuart_port *, char ch);
274
	void		(*stop_rx)(struct rdpuart_port *);
275
	void		(*enable_ms)(struct rdpuart_port *);
276
	void		(*break_ctl)(struct rdpuart_port *, int ctl);
277
	int		(*startup)(struct rdpuart_port *);
278
	void		(*shutdown)(struct rdpuart_port *);
279
	void		(*flush_buffer)(struct rdpuart_port *);
280
	void		(*set_termios)(struct rdpuart_port *, struct ktermios *new,
281
				       struct ktermios *old);
282
	void		(*set_ldisc)(struct rdpuart_port *);
283
	void		(*pm)(struct rdpuart_port *, unsigned int state,
284
			      unsigned int oldstate);
285
	int		(*set_wake)(struct rdpuart_port *, unsigned int state);
286
287
	/*
288
	 * Return a string describing the type of the port
289
	 */
290
	const char *(*type)(struct rdpuart_port *);
291
292
	/*
293
	 * Release IO and memory resources used by the port.
294
	 * This includes iounmap if necessary.
295
	 */
296
	void		(*release_port)(struct rdpuart_port *);
297
298
	/*
299
	 * Request IO and memory resources used by the port.
300
	 * This includes iomapping the port if necessary.
301
	 */
302
	int		(*request_port)(struct rdpuart_port *);
303
	void		(*config_port)(struct rdpuart_port *, int);
304
	int		(*verify_port)(struct rdpuart_port *, struct serial_struct *);
305
	int		(*ioctl)(struct rdpuart_port *, unsigned int, unsigned long);
306
#ifdef CONFIG_CONSOLE_POLL
307
	void		(*poll_put_char)(struct rdpuart_port *, unsigned char);
308
	int		(*poll_get_char)(struct rdpuart_port *);
309
#endif
310
} rdpuart_ops_t;
311
312
313
#endif	/* __KERNEL__			*/
314
315
#ifndef WIN32_SERIAL
316
317
#define  MAX_BAUD_RATE              460800
318
#define  MAX_BAUD_REMAINDER         4608
319
320
#define  DIV_LATCH_LS               0x00
321
#define  XMT_HOLD_REGISTER          0x00
322
#define  XVR_BUFFER_REGISTER        0x00
323
#define  DIV_LATCH_MS               0x01
324
#define  FIFO_CONTROL_REGISTER      0x02
325
#define  LINE_CONTROL_REGISTER      0x03
326
#define  MODEM_CONTROL_REGISTER     0x04
327
#define  LINE_STATUS_REGISTER       0x05
328
#define  MODEM_STATUS_REGISTER      0x06
329
330
#define  SERIAL_MCR_DTR             0x01
331
#define  SERIAL_MCR_RTS             0x02
332
#define  SERIAL_MCR_LOOP            0x10
333
334
#define  SERIAL_MSR_CTS             0x10
335
#define  SERIAL_MSR_CD              0x80
336
#define  SERIAL_MSR_RI              0x40
337
#define  SERIAL_MSR_DSR             0x20
338
#define  SERIAL_MSR_MASK            0xf0
339
340
#define  SERIAL_8_DATA              0x03
341
#define  SERIAL_7_DATA              0x02
342
#define  SERIAL_6_DATA              0x01
343
#define  SERIAL_5_DATA              0x00
344
345
#define  SERIAL_ODD_PARITY          0X08
346
#define  SERIAL_EVEN_PARITY         0X18
347
#define  SERIAL_TWO_STOPB           0x04
348
#define  SERIAL_ONE_STOPB           0x00
349
350
#define DEFAULT_DIVISOR  0x30	/* gives 9600 baud rate */
351
#define DEFAULT_LCR SERIAL_8_DATA	/* 8, none , 1 */
352
353
#define SERIAL_LSR_OE       0x02
354
#define SERIAL_LSR_PE       0x04
355
#define SERIAL_LSR_FE       0x08
356
#define SERIAL_LSR_BI       0x10
357
358
#define  SERIAL_MSR_CTS             0x10
359
#define  SERIAL_MSR_CD              0x80
360
#define  SERIAL_MSR_RI              0x40
361
#define  SERIAL_MSR_DSR             0x20
362
#define  SERIAL_MSR_MASK            0xf0
363
364
#define LOOPMODE_BITS       0x41	/* LOOP1 = b6, LOOP0 = b0 (PORT B) */
365
#define ALL_LOOPBACK        0x01
366
#define MODEM_CTRL          0x40
367
#define RS232_MODE          0x00
368
369
#endif
370
371
#endif	/* LINUX_RDPUART_H		*/
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/reply.c (+307 lines)
Line 0    Link Here 
1
/*
2
 * 	reply.c
3
 *
4
 * Copyright (c) 2004+ Evgeniy Polyakov <zbr[AT]ioremap[DOT]net>
5
 *
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
 */
21
22
#include <asm/types.h>
23
24
#include <sys/types.h>
25
#include <sys/socket.h>
26
#include <sys/poll.h>
27
28
#include <linux/netlink.h>
29
#include <linux/rtnetlink.h>
30
31
#include <arpa/inet.h>
32
33
#include <stdbool.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <unistd.h>
37
#include <string.h>
38
#include <errno.h>
39
#include <time.h>
40
#include <getopt.h>
41
42
#include <linux/connector.h>
43
#include <linux/serial.h>
44
#include <linux/rdpuart.h>
45
46
#include "common/os_calls.h"
47
48
#define DEBUG
49
#ifndef NETLINK_CONNECTOR
50
#define NETLINK_CONNECTOR 	11
51
#endif
52
53
/* Hopefully your userspace connector.h matches this kernel */
54
/* #define CN_TEST_IDX		CN_NETLINK_USERS + 3	*/
55
/* #define CN_TEST_VAL		0x456			*/
56
#define	CN_TEST_IDX		CN_IDX_RDPUART
57
#define CN_TEST_VAL		CN_VAL_RDPUART
58
59
#ifdef DEBUG
60
#define ulog(f, a...) fprintf(stdout, f, ##a)
61
#else
62
#define ulog(f, a...) do {} while (0)
63
#endif
64
65
66
static const char * cmdarray[] = CMD_TO_STRING_ARRAY_DEF;
67
68
#define RDPUARTCMD(x) (cmdarray[(x & 0x0f)])
69
70
71
static int need_exit;
72
static __u32 seq;
73
74
static int netlink_send(int s, struct cn_msg * msg) {
75
	struct nlmsghdr * nlh = (struct nlmsghdr *)NULL;
76
	unsigned int size = 0;
77
	int err = 0;
78
	struct cn_msg * m = (struct cn_msg *)NULL;
79
	rdpuart_netlink_msg * rmsg = (rdpuart_netlink_msg *)NULL;
80
	char buf[128];
81
82
	memset(buf, 0, sizeof(char) * 128);
83
	size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
84
85
	nlh = (struct nlmsghdr *)buf;
86
	nlh->nlmsg_seq = seq++;
87
	nlh->nlmsg_pid = getpid();
88
	nlh->nlmsg_type = NLMSG_DONE;
89
	nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
90
	nlh->nlmsg_flags = 0;
91
92
	m = NLMSG_DATA(nlh);
93
#if 0
94
	ulog("%s: [%08x.%08x] len=%u, seq=%u, ack=%u.\n",
95
	       __func__, msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack);
96
#endif
97
	memcpy(m, msg, sizeof(*m) + msg->len);
98
99
	err = send(s, nlh, size, 0);
100
	if (err == -1)
101
		ulog("Failed to send: %s [%d].\n",
102
			strerror(errno), errno);
103
104
	g_hexdump_file("/tmp/reply.hex", buf, size);
105
106
	return err;
107
}
108
109
static void usage(void) {
110
	printf(
111
		"Usage: reply [options] [output file]\n"
112
		"\n"
113
		"\t-h\tthis help screen\n"
114
		"\t-r\tsend reply packets in response to inbound packets received from the test module\n"
115
		"\t-s\tsend buffers to the test module\n"
116
		"\n"
117
		"The default behavior of reply is to subscribe to the test module\n"
118
		"and wait for state messages.  Any ones received are dumped to the\n"
119
		"specified output file (or stdout).  The test module is assumed to\n"
120
		"have an id of {%u.%u}\n"
121
		"\n"
122
		"If you get no output, then verify the cn_test module id matches\n"
123
		"the expected id above.\n", CN_TEST_IDX, CN_TEST_VAL);
124
}
125
126
int main(int argc, char *argv[]) {
127
	int s = 0;
128
	int res = 0;
129
	int len = 0;
130
	struct nlmsghdr * reply = (struct nlmsghdr *)NULL;
131
	struct cn_msg * data = (struct cn_msg *)NULL;
132
	FILE * out = (FILE *)NULL;
133
	bool send_msgs = false;
134
	bool send_rply = false;
135
	struct sockaddr_nl l_local;
136
	time_t tm;
137
	struct pollfd pfd;
138
	char buf[1024];
139
140
	memset(&l_local, 0, sizeof(struct sockaddr_nl));
141
	memset(&tm, 0, sizeof(time_t));
142
	memset(&pfd, 0, sizeof(struct pollfd));
143
	memset(buf, 0, sizeof(char) * 1024);
144
145
	while ((s = getopt(argc, argv, "hrs")) != -1) {
146
		switch (s) {
147
		case 'r':
148
			send_rply = true;
149
			break;
150
151
		case 's':
152
			send_msgs = true;
153
			break;
154
155
		case 'h':
156
			usage();
157
			res = 0;
158
			return res;
159
160
		default:
161
			/* getopt() outputs an error for us */
162
			usage();
163
			res = 1;
164
			return res;
165
		}
166
	}
167
168
	if (argc != optind) {
169
	  out = fopen(argv[optind], "a+");
170
	  if (!out) {
171
	    ulog("Unable to open %s for writing: %s\n", argv[1], strerror(errno));
172
	    out = stdout;
173
	  }
174
	}
175
	else {
176
	  out = stdout;
177
	}
178
179
	memset(buf, 0, sizeof(buf));
180
181
	if ((s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR)) < 0) {
182
	  perror("socket");
183
	  res = s;
184
	  return res;
185
	}
186
187
	l_local.nl_family = AF_NETLINK;
188
	l_local.nl_groups = -1; /* bitmask of requested groups */
189
	l_local.nl_pid = 0;
190
191
	ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL);
192
193
	if ((res = bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl))) < 0) {
194
	  perror("bind");
195
	  close(s);
196
	  return res;
197
	}
198
199
#if 0
200
	ulog("  >> 0 is defined <<\n");
201
	{
202
	  int on = 0x57; /* Additional group number */
203
	  setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
204
	}
205
#endif
206
	if (send_msgs) {
207
	  int i = 0;
208
	  int j = 0;
209
210
	  memset(buf, 0, sizeof(buf));
211
	  data = (struct cn_msg *)buf;
212
	  data->id.idx = CN_TEST_IDX;
213
	  data->id.val = CN_TEST_VAL;
214
	  data->seq = seq++;
215
	  data->ack = 0;
216
	  data->len = sizeof(struct cn_msg) * 3;
217
218
	  for (j = 0; j < 10; ++j) {
219
	    for (i = 0; i < 100; ++i) {
220
	      len = netlink_send(s, data);
221
	    }
222
	    ulog("%d messages have been sent to %08x.%08x.\n", i, data->id.idx, data->id.val);
223
	  }
224
	  return 0;
225
	}
226
227
	pfd.fd = s;
228
229
	while (!need_exit) {
230
		pfd.events = POLLIN;
231
		pfd.revents = 0;
232
		switch (poll(&pfd, 1, -1)) {
233
			case 0:
234
				need_exit = 1;
235
				break;
236
			case -1:
237
				if (errno != EINTR) {
238
					need_exit = 1;
239
					break;
240
				}
241
				continue;
242
		}
243
		if (need_exit) {
244
		  break;
245
		}
246
247
		memset(buf, 0, sizeof(buf));
248
		if ((len = recv(s, buf, sizeof(buf), 0)) < 0) {
249
			perror("recv buf");
250
			close(s);
251
			res = len;
252
			return res;
253
		}
254
		reply = (struct nlmsghdr *)buf;
255
256
		switch (reply->nlmsg_type) {
257
		case NLMSG_ERROR:
258
			fprintf(out, "Error message received.\n");
259
			fflush(out);
260
			break;
261
		case NLMSG_DONE:
262
			{
263
			  int seqid = 0;
264
			  int idx = 0;
265
			  int val = 0;
266
			  int ack = 0;
267
268
			  data = (struct cn_msg *)NLMSG_DATA(reply);
269
			  rdpuart_netlink_msg * rdpmsg = (rdpuart_netlink_msg *)data->data;
270
271
			  seqid = data->seq;
272
			  idx = data->id.idx;
273
			  val = data->id.val;
274
			  ack = data->ack;
275
276
			  time(&tm);
277
			  fprintf(out, "%.24s : [%x.%x] [%08u.%08u] --> ",
278
			    ctime(&tm), data->id.idx, data->id.val, data->seq, data->ack);
279
			  fprintf(out, "\"%s\" \t (len = \"%d\")\n", RDPUARTCMD(rdpmsg->type), rdpmsg->type, rdpmsg->len);
280
			  fflush(out);
281
			  if (send_rply) {
282
			    unsigned char * tp = (unsigned char *)NULL;
283
			    unsigned char tbuf[1024];
284
			    memset(tbuf, 0, sizeof(tbuf));
285
			    data = (struct cn_msg *)tbuf;
286
			    data->id.idx = CN_TEST_IDX;
287
			    data->id.val = CN_TEST_VAL;
288
			    data->seq = seqid;
289
			    data->ack = 1;
290
//			    data->len = sizeof(struct cn_msg) * 1;
291
			    data->len = sizeof(rdpuart_netlink_msg) * 1;
292
			    tp = (unsigned char *)data->data;
293
			    memcpy(data->data, rdpmsg, sizeof(rdpuart_netlink_msg));
294
			    len = netlink_send(s, data);
295
296
			    ulog(" --> reply sent to %08x.%08x.\n", idx, val);
297
			  }
298
			}
299
			break;
300
		default:
301
			break;
302
		}
303
	}
304
305
	close(s);
306
	return res;
307
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/linux/ucon.c (+265 lines)
Line 0    Link Here 
1
/*
2
 * 	ucon.c
3
 *
4
 * Copyright (c) 2004+ Evgeniy Polyakov <zbr[AT]ioremap[DOT]net>
5
 *
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
 */
21
22
#include <asm/types.h>
23
24
#include <sys/types.h>
25
#include <sys/socket.h>
26
#include <sys/poll.h>
27
28
#include <linux/netlink.h>
29
#include <linux/rtnetlink.h>
30
31
#include <arpa/inet.h>
32
33
#include <stdbool.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <unistd.h>
37
#include <string.h>
38
#include <errno.h>
39
#include <time.h>
40
#include <getopt.h>
41
42
#include <linux/connector.h>
43
#include <linux/serial.h>
44
#include <linux/rdpuart.h>
45
46
#define DEBUG
47
#define NETLINK_CONNECTOR 	11
48
49
/* Hopefully your userspace connector.h matches this kernel */
50
/* #define CN_TEST_IDX		CN_NETLINK_USERS + 3	*/
51
/* #define CN_TEST_VAL		0x456			*/
52
#define	CN_TEST_IDX		CN_IDX_RDPUART
53
#define CN_TEST_VAL		CN_VAL_RDPUART
54
55
#ifdef DEBUG
56
#define ulog(f, a...) fprintf(stdout, f, ##a)
57
#else
58
#define ulog(f, a...) do {} while (0)
59
#endif
60
61
62
static const char * cmdarray[] = CMD_TO_STRING_ARRAY_DEF;
63
64
#define RDPUARTCMD(x) (cmdarray[(x & 0x0f)])
65
66
67
static int need_exit;
68
static __u32 seq;
69
70
static int netlink_send(int s, struct cn_msg *msg) {
71
	struct nlmsghdr *nlh;
72
	unsigned int size;
73
	int err;
74
	char buf[128];
75
	struct cn_msg *m;
76
	rdpuart_netlink_msg * rmsg = (rdpuart_netlink_msg *)NULL;
77
78
	size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
79
80
	nlh = (struct nlmsghdr *)buf;
81
	nlh->nlmsg_seq = seq++;
82
	nlh->nlmsg_pid = getpid();
83
	nlh->nlmsg_type = NLMSG_DONE;
84
	nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
85
	nlh->nlmsg_flags = 0;
86
87
	m = NLMSG_DATA(nlh);
88
#if 0
89
	ulog("%s: [%08x.%08x] len=%u, seq=%u, ack=%u.\n",
90
	       __func__, msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack);
91
#endif
92
	memcpy(m, msg, sizeof(*m) + msg->len);
93
94
	err = send(s, nlh, size, 0);
95
	if (err == -1)
96
		ulog("Failed to send: %s [%d].\n",
97
			strerror(errno), errno);
98
99
	return err;
100
}
101
102
static void usage(void)
103
{
104
	printf(
105
		"Usage: ucon [options] [output file]\n"
106
		"\n"
107
		"\t-h\tthis help screen\n"
108
		"\t-s\tsend buffers to the test module\n"
109
		"\n"
110
		"The default behavior of ucon is to subscribe to the test module\n"
111
		"and wait for state messages.  Any ones received are dumped to the\n"
112
		"specified output file (or stdout).  The test module is assumed to\n"
113
		"have an id of {%u.%u}\n"
114
		"\n"
115
		"If you get no output, then verify the cn_test module id matches\n"
116
		"the expected id above.\n", CN_TEST_IDX, CN_TEST_VAL);
117
}
118
119
int main(int argc, char *argv[]) {
120
	int s = 0;
121
	int res = 0;
122
	int len = 0;
123
	struct nlmsghdr * reply = (struct nlmsghdr *)NULL;
124
	struct cn_msg * data = (struct cn_msg *)NULL;
125
	FILE * out = (FILE *)NULL;
126
	bool send_msgs = false;
127
	struct sockaddr_nl l_local;
128
	time_t tm;
129
	struct pollfd pfd;
130
	char buf[1024];
131
132
	while ((s = getopt(argc, argv, "hs")) != -1) {
133
		switch (s) {
134
		case 's':
135
			send_msgs = true;
136
			break;
137
138
		case 'h':
139
			usage();
140
			res = 0;
141
			return res;
142
143
		default:
144
			/* getopt() outputs an error for us */
145
			usage();
146
			res = 1;
147
			return res;
148
		}
149
	}
150
151
	if (argc != optind) {
152
		out = fopen(argv[optind], "a+");
153
		if (!out) {
154
			ulog("Unable to open %s for writing: %s\n",
155
				argv[1], strerror(errno));
156
			out = stdout;
157
		}
158
	} else {
159
		out = stdout;
160
	}
161
162
	memset(buf, 0, sizeof(buf));
163
164
	if ((s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR)) < 0) {
165
		perror("socket");
166
		res = s;
167
		return res;
168
	}
169
170
	l_local.nl_family = AF_NETLINK;
171
	l_local.nl_groups = -1; /* bitmask of requested groups */
172
	l_local.nl_pid = 0;
173
174
	ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL);
175
176
	if ((res = bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl))) < 0) {
177
		perror("bind");
178
		close(s);
179
		return res;
180
	}
181
182
#if 0
183
	{
184
		int on = 0x57; /* Additional group number */
185
		setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
186
	}
187
#endif
188
	if (send_msgs) {
189
		int i = 0;
190
		int j = 0;
191
192
		memset(buf, 0, sizeof(buf));
193
194
		data = (struct cn_msg *)buf;
195
196
		data->id.idx = CN_TEST_IDX;
197
		data->id.val = CN_TEST_VAL;
198
		data->seq = seq++;
199
		data->ack = 0;
200
		data->len = sizeof(struct cn_msg) * 3;
201
202
		for (j=0; j<10; ++j) {
203
		  for (i=0; i<100; ++i) {
204
		    len = netlink_send(s, data);
205
		  }
206
		  ulog("%d messages have been sent to %08x.%08x.\n", i, data->id.idx, data->id.val);
207
		}
208
		return 0;
209
	}
210
211
212
	pfd.fd = s;
213
214
	while (!need_exit) {
215
		pfd.events = POLLIN;
216
		pfd.revents = 0;
217
		switch (poll(&pfd, 1, -1)) {
218
			case 0:
219
				need_exit = 1;
220
				break;
221
			case -1:
222
				if (errno != EINTR) {
223
					need_exit = 1;
224
					break;
225
				}
226
				continue;
227
		}
228
		if (need_exit) {
229
		  break;
230
		}
231
232
		memset(buf, 0, sizeof(buf));
233
		if ((len = recv(s, buf, sizeof(buf), 0)) < 0) {
234
			perror("recv buf");
235
			close(s);
236
			res = len;
237
			return res;
238
		}
239
		reply = (struct nlmsghdr *)buf;
240
241
		switch (reply->nlmsg_type) {
242
		case NLMSG_ERROR:
243
			fprintf(out, "Error message received.\n");
244
			fflush(out);
245
			break;
246
		case NLMSG_DONE:
247
			{
248
			data = (struct cn_msg *)NLMSG_DATA(reply);
249
			rdpuart_netlink_msg * rdpmsg = (rdpuart_netlink_msg *)data->data;
250
251
			time(&tm);
252
			fprintf(out, "%.24s : [%x.%x] [%08u.%08u] --> ",
253
				ctime(&tm), data->id.idx, data->id.val, data->seq, data->ack);
254
			fprintf(out, "\"%s\" \t (len = \"%d\")\n", RDPUARTCMD(rdpmsg->type), rdpmsg->type, rdpmsg->len);
255
			fflush(out);
256
			}
257
			break;
258
		default:
259
			break;
260
		}
261
	}
262
263
	close(s);
264
	return res;
265
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/mc/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 14-17    Link Here 
14
libmc_la_SOURCES = mc.c
22
libmc_la_SOURCES = mc.c
15
23
16
libmc_la_LIBADD = \
24
libmc_la_LIBADD = \
17
  $(top_srcdir)/common/libcommon.la
25
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/project.log (+24 lines)
Line 0    Link Here 
1
2009-10-30 14:33:49     INFO: Bootstrapping "project" in "/usr/src/xrdp/trunk"
2
2009-10-30 14:33:49    DEBUG: cvs not found as new-style vcs, trying as monolithic
3
2009-10-30 14:33:49    DEBUG: bzr not found as new-style vcs, trying as monolithic
4
2009-10-30 14:33:49     INFO: Initializing new repository in '/usr/src/xrdp/trunk'...
5
2009-10-30 14:33:49     INFO: $ cvs -f -d /usr/src/xrdp/cvs rlog -r:HEAD -b xrdp 2>&1
6
2009-10-30 14:33:49    DEBUG: Executing  cvs -f -d /usr/src/xrdp/cvs rlog -r:HEAD -b xrdp ('/usr/src/xrdp')
7
2009-10-30 14:33:49     INFO: [Ok]
8
2009-10-30 14:33:49     INFO: Cached information about 0 pending changesets
9
2009-10-30 14:33:49 CRITICAL: Checkout of project failed!
10
2009-10-30 14:33:49 CRITICAL: Something unexpected!
11
Traceback (most recent call last):
12
  File "/usr/lib/pymodules/python2.5/vcpx/tailor.py", line 153, in __call__
13
    self.bootstrap()
14
  File "/usr/lib/pymodules/python2.5/vcpx/tailor.py", line 80, in bootstrap
15
    actual = dwd.checkoutUpstreamRevision(revision)
16
  File "/usr/lib/pymodules/python2.5/vcpx/source.py", line 242, in checkoutUpstreamRevision
17
    last = self._checkoutUpstreamRevision(revision)
18
  File "/usr/lib/pymodules/python2.5/vcpx/repository/cvs.py", line 681, in _checkoutUpstreamRevision
19
    last = CvspsWorkingDir._checkoutUpstreamRevision(self, revision)
20
  File "/usr/lib/pymodules/python2.5/vcpx/repository/cvsps.py", line 446, in _checkoutUpstreamRevision
21
    initialcset = csets.next()
22
  File "/usr/lib/pymodules/python2.5/vcpx/statefile.py", line 108, in next
23
    raise StopIteration
24
StopIteration
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/rdp/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 23-26    Link Here 
23
  rdp_tcp.c
31
  rdp_tcp.c
24
32
25
librdp_la_LIBADD = \
33
librdp_la_LIBADD = \
26
  $(top_srcdir)/common/libcommon.la
34
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/rdp/rdp_orders.c (-100 / +178 lines)
 Lines 22-32    Link Here 
22
22
23
#include "rdp.h"
23
#include "rdp.h"
24
24
25
#ifndef NULL
26
#define NULL 0
27
#endif
28
25
/*****************************************************************************/
29
/*****************************************************************************/
26
struct rdp_orders* APP_CC
30
struct rdp_orders* APP_CC
27
rdp_orders_create(struct rdp_rdp* owner)
31
rdp_orders_create(struct rdp_rdp* owner)
28
{
32
{
29
  struct rdp_orders* self;
33
  struct rdp_orders* self = (struct rdp_orders *)NULL;
30
34
31
  self = (struct rdp_orders*)g_malloc(sizeof(struct rdp_orders), 1);
35
  self = (struct rdp_orders*)g_malloc(sizeof(struct rdp_orders), 1);
32
  self->rdp_layer = owner;
36
  self->rdp_layer = owner;
 Lines 37-44    Link Here 
37
void APP_CC
41
void APP_CC
38
rdp_orders_delete(struct rdp_orders* self)
42
rdp_orders_delete(struct rdp_orders* self)
39
{
43
{
40
  int i;
44
  int i = 0;
41
  int j;
45
  int j = 0;
42
46
43
  if (self == 0)
47
  if (self == 0)
44
  {
48
  {
 Lines 77-84    Link Here 
77
rdp_orders_in_present(struct stream* s, int* present,
81
rdp_orders_in_present(struct stream* s, int* present,
78
                      int flags, int size)
82
                      int flags, int size)
79
{
83
{
80
  int bits;
84
  int bits = 0;
81
  int i;
85
  int i = 0;
82
86
83
  if (flags & RDP_ORDER_SMALL)
87
  if (flags & RDP_ORDER_SMALL)
84
  {
88
  {
 Lines 108-114    Link Here 
108
static void APP_CC
112
static void APP_CC
109
rdp_orders_in_coord(struct stream* s, int* coord, int delta)
113
rdp_orders_in_coord(struct stream* s, int* coord, int delta)
110
{
114
{
111
  int change;
115
  int change = 0;
112
116
113
  if (delta)
117
  if (delta)
114
  {
118
  {
 Lines 126-132    Link Here 
126
static void APP_CC
130
static void APP_CC
127
rdp_orders_parse_bounds(struct rdp_orders* self, struct stream* s)
131
rdp_orders_parse_bounds(struct rdp_orders* self, struct stream* s)
128
{
132
{
129
  int present;
133
  int present = 0;
130
134
131
  in_uint8(s, present);
135
  in_uint8(s, present);
132
  if (present & 1)
136
  if (present & 1)
 Lines 169-178    Link Here 
169
rdp_orders_process_colcache(struct rdp_orders* self, struct stream* s,
173
rdp_orders_process_colcache(struct rdp_orders* self, struct stream* s,
170
                            int flags)
174
                            int flags)
171
{
175
{
172
  struct rdp_colormap* colormap;
176
  struct rdp_colormap* colormap = (struct rdp_colormap *)NULL;
173
  struct stream* rec_s;
177
  struct stream* rec_s = (struct stream *)NULL;
174
  int cache_id;
178
  int cache_id = 0;
175
  int i;
179
  int i = 0;
176
180
177
  colormap = (struct rdp_colormap*)g_malloc(sizeof(struct rdp_colormap), 1);
181
  colormap = (struct rdp_colormap*)g_malloc(sizeof(struct rdp_colormap), 1);
178
  in_uint8(s, cache_id);
182
  in_uint8(s, cache_id);
 Lines 206-231    Link Here 
206
rdp_orders_process_raw_bmpcache(struct rdp_orders* self, struct stream* s,
210
rdp_orders_process_raw_bmpcache(struct rdp_orders* self, struct stream* s,
207
                                int flags)
211
                                int flags)
208
{
212
{
209
  int cache_idx;
213
  int cache_idx = 0;
210
  int bufsize;
214
  int bufsize = 0;
211
  int cache_id;
215
  int cache_id = 0;
212
  int width;
216
  int width = 0;
213
  int height;
217
  int height = 0;
214
  int bpp;
218
  int bpp = 0;
215
  int Bpp;
219
  int Bpp = 0;
216
  int x;
220
  int x = 0;
217
  int y;
221
  int y = 0;
218
  char* inverted;
222
  char* inverted = (char *)NULL;
219
  char* dst;
223
  char* dst = (char *)NULL;
220
  struct rdp_bitmap* bitmap;
224
  struct rdp_bitmap* bitmap = (struct rdp_bitmap *)NULL;
221
  struct stream* rec_s;
225
  struct stream* rec_s = (struct stream *)NULL;
222
226
223
  in_uint8(s, cache_id);
227
  in_uint8(s, cache_id);
224
  in_uint8s(s, 1);
228
  in_uint8s(s, 1);
225
  in_uint8(s, width);
229
  in_uint8(s, width);
226
  in_uint8(s, height);
230
  in_uint8(s, height);
227
  in_uint8(s, bpp);
231
  in_uint8(s, bpp);
228
  Bpp = (bpp + 7) / 8;
232
  Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
229
  in_uint16_le(s, bufsize);
233
  in_uint16_le(s, bufsize);
230
  in_uint16_le(s, cache_idx);
234
  in_uint16_le(s, cache_idx);
231
  inverted = (char*)g_malloc(width * height * Bpp, 0);
235
  inverted = (char*)g_malloc(width * height * Bpp, 0);
 Lines 255-265    Link Here 
255
        in_uint8(s, dst[x * 3 + 2]);
259
        in_uint8(s, dst[x * 3 + 2]);
256
      }
260
      }
257
    }
261
    }
262
    else if (Bpp == 4)
263
    {
264
      for (x = 0; x < width; x++)
265
      {
266
        in_uint32_le(s, ((tui32*)dst)[x]);
267
      }
268
    }
258
  }
269
  }
259
  bitmap = (struct rdp_bitmap*)g_malloc(sizeof(struct rdp_bitmap), 0);
270
  bitmap = (struct rdp_bitmap*)g_malloc(sizeof(struct rdp_bitmap), 0);
260
  bitmap->width = width;
271
  bitmap->width = width;
261
  bitmap->height = height;
272
  bitmap->height = height;
262
  bitmap->bpp = bpp;
273
  bitmap->bpp = (bpp == 32) ? 24 : bpp;
263
  bitmap->data = inverted;
274
  bitmap->data = inverted;
264
  if (self->cache_bitmap[cache_id][cache_idx] != 0)
275
  if (self->cache_bitmap[cache_id][cache_idx] != 0)
265
  {
276
  {
 Lines 292-320    Link Here 
292
rdp_orders_process_bmpcache(struct rdp_orders* self, struct stream* s,
303
rdp_orders_process_bmpcache(struct rdp_orders* self, struct stream* s,
293
                            int flags)
304
                            int flags)
294
{
305
{
295
  char* data;
306
  char* data = (char *)NULL;
296
  char* bmpdata;
307
  char* bmpdata = (char *)NULL;
297
  int cache_idx;
308
  int cache_idx = 0;
298
  int size;
309
  int size = 0;
299
  int cache_id;
310
  int cache_id = 0;
300
  int width;
311
  int width = 0;
301
  int height;
312
  int height = 0;
302
  int bpp;
313
  int bpp = 0;
303
  int Bpp;
314
  int Bpp = 0;
304
  int bufsize;
315
  int bufsize = 0;
305
  int pad1;
316
  int pad1 = 0;
306
  int pad2;
317
  int pad2 = 0;
307
  int row_size;
318
  int row_size = 0;
308
  int final_size;
319
  int final_size = 0;
309
  struct rdp_bitmap* bitmap;
320
  struct rdp_bitmap* bitmap = (struct rdp_bitmap *)NULL;
310
  struct stream* rec_s;
321
  struct stream* rec_s = (struct stream *)NULL;
311
322
312
  in_uint8(s, cache_id);
323
  in_uint8(s, cache_id);
313
  in_uint8(s, pad1);
324
  in_uint8(s, pad1);
314
  in_uint8(s, width);
325
  in_uint8(s, width);
315
  in_uint8(s, height);
326
  in_uint8(s, height);
316
  in_uint8(s, bpp);
327
  in_uint8(s, bpp);
317
  Bpp = (bpp + 7) / 8;
328
  Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
318
  in_uint16_le(s, bufsize);
329
  in_uint16_le(s, bufsize);
319
  in_uint16_le(s, cache_idx);
330
  in_uint16_le(s, cache_idx);
320
  if (flags & 1024)
331
  if (flags & 1024)
 Lines 340-346    Link Here 
340
  bitmap = (struct rdp_bitmap*)g_malloc(sizeof(struct rdp_bitmap), 0);
351
  bitmap = (struct rdp_bitmap*)g_malloc(sizeof(struct rdp_bitmap), 0);
341
  bitmap->width = width;
352
  bitmap->width = width;
342
  bitmap->height = height;
353
  bitmap->height = height;
343
  bitmap->bpp = bpp;
354
  bitmap->bpp = (bpp == 32) ? 24 : bpp;
344
  bitmap->data = bmpdata;
355
  bitmap->data = bmpdata;
345
  if (self->cache_bitmap[cache_id][cache_idx] != 0)
356
  if (self->cache_bitmap[cache_id][cache_idx] != 0)
346
  {
357
  {
 Lines 373-389    Link Here 
373
rdp_orders_process_fontcache(struct rdp_orders* self, struct stream* s,
384
rdp_orders_process_fontcache(struct rdp_orders* self, struct stream* s,
374
                             int flags)
385
                             int flags)
375
{
386
{
376
  struct stream* rec_s;
387
  struct stream* rec_s = (struct stream *)NULL;
377
  int font;
388
  int font = 0;
378
  int nglyphs;
389
  int nglyphs = 0;
379
  int character;
390
  int character = 0;
380
  int offset;
391
  int offset = 0;
381
  int baseline;
392
  int baseline = 0;
382
  int width;
393
  int width = 0;
383
  int height;
394
  int height = 0;
384
  int i;
395
  int i = 0;
385
  int datasize;
396
  int datasize = 0;
386
  char* data;
397
  char* data = (char *)NULL;
387
398
388
  in_uint8(s, font);
399
  in_uint8(s, font);
389
  in_uint8(s, nglyphs);
400
  in_uint8(s, nglyphs);
 Lines 425-434    Link Here 
425
static int APP_CC
436
static int APP_CC
426
rdp_orders_process_secondary_order(struct rdp_orders* self, struct stream* s)
437
rdp_orders_process_secondary_order(struct rdp_orders* self, struct stream* s)
427
{
438
{
428
  short length;
439
  short length = 0;
429
  int flags;
440
  int flags = 0;
430
  int type;
441
  int type = 0;
431
  char* next_order;
442
  char* next_order = (char *)NULL;
432
443
433
  in_uint16_le(s, length);
444
  in_uint16_le(s, length);
434
  in_uint16_le(s, flags);
445
  in_uint16_le(s, flags);
 Lines 461-467    Link Here 
461
static void APP_CC
472
static void APP_CC
462
rdp_orders_in_color(struct stream* s, int* color)
473
rdp_orders_in_color(struct stream* s, int* color)
463
{
474
{
464
  int i;
475
  int i = 0;
465
476
466
  in_uint8(s, i);
477
  in_uint8(s, i);
467
  *color = i;
478
  *color = i;
 Lines 523-531    Link Here 
523
rdp_orders_process_text2(struct rdp_orders* self, struct stream* s,
534
rdp_orders_process_text2(struct rdp_orders* self, struct stream* s,
524
                         int present, int delta)
535
                         int present, int delta)
525
{
536
{
526
  int fgcolor;
537
  int fgcolor = 0;
527
  int bgcolor;
538
  int bgcolor = 0;
528
  struct stream* rec_s;
539
  struct stream* rec_s = (struct stream *)NULL;
529
540
530
  if (present & 0x000001)
541
  if (present & 0x000001)
531
  {
542
  {
 Lines 662-668    Link Here 
662
rdp_orders_process_destblt(struct rdp_orders* self, struct stream* s,
673
rdp_orders_process_destblt(struct rdp_orders* self, struct stream* s,
663
                           int present, int delta)
674
                           int present, int delta)
664
{
675
{
665
  struct stream* rec_s;
676
  struct stream* rec_s = (struct stream *)NULL;
666
677
667
  if (present & 0x01)
678
  if (present & 0x01)
668
  {
679
  {
 Lines 715-723    Link Here 
715
rdp_orders_process_patblt(struct rdp_orders* self, struct stream* s,
726
rdp_orders_process_patblt(struct rdp_orders* self, struct stream* s,
716
                          int present, int delta)
727
                          int present, int delta)
717
{
728
{
718
  int fgcolor;
729
  int fgcolor = 0;
719
  int bgcolor;
730
  int bgcolor = 0;
720
  struct stream* rec_s;
731
  struct stream* rec_s = (struct stream *)NULL;
721
732
722
  if (present & 0x0001)
733
  if (present & 0x0001)
723
  {
734
  {
 Lines 867-875    Link Here 
867
rdp_orders_process_line(struct rdp_orders* self, struct stream* s,
878
rdp_orders_process_line(struct rdp_orders* self, struct stream* s,
868
                        int present, int delta)
879
                        int present, int delta)
869
{
880
{
870
  int bgcolor;
881
  int bgcolor = 0;
871
  int fgcolor;
882
  int fgcolor = 0;
872
  struct stream* rec_s;
883
  struct stream* rec_s = (struct stream *)NULL;
873
884
874
  if (present & 0x0001)
885
  if (present & 0x0001)
875
  {
886
  {
 Lines 949-957    Link Here 
949
rdp_orders_process_rect(struct rdp_orders* self, struct stream* s,
960
rdp_orders_process_rect(struct rdp_orders* self, struct stream* s,
950
                        int present, int delta)
961
                        int present, int delta)
951
{
962
{
952
  int i;
963
  int i = 0;
953
  int fgcolor;
964
  int fgcolor = 0;
954
  struct stream* rec_s;
965
  struct stream* rec_s = (struct stream *)NULL;
955
966
956
  if (present & 0x01)
967
  if (present & 0x01)
957
  {
968
  {
 Lines 1017-1024    Link Here 
1017
rdp_orders_process_desksave(struct rdp_orders* self, struct stream* s,
1028
rdp_orders_process_desksave(struct rdp_orders* self, struct stream* s,
1018
                            int present, int delta)
1029
                            int present, int delta)
1019
{
1030
{
1020
  int width;
1031
  int width = 0;
1021
  int height;
1032
  int height = 0;
1022
1033
1023
  if (present & 0x01)
1034
  if (present & 0x01)
1024
  {
1035
  {
 Lines 1044-1051    Link Here 
1044
  {
1055
  {
1045
    in_uint8(s, self->state.desksave_action);
1056
    in_uint8(s, self->state.desksave_action);
1046
  }
1057
  }
1047
//  width = (self->state.desksave_right - self->state.desksave_left) + 1;
1058
  width = (self->state.desksave_right - self->state.desksave_left) + 1;
1048
//  height = (self->state.desksave_bottom - self->state.desksave_top) + 1;
1059
  height = (self->state.desksave_bottom - self->state.desksave_top) + 1;
1049
  if (self->state.desksave_action == 0)
1060
  if (self->state.desksave_action == 0)
1050
  {
1061
  {
1051
//		ui_desktop_save(os->offset, os->left, os->top, width, height);
1062
//		ui_desktop_save(os->offset, os->left, os->top, width, height);
 Lines 1062-1070    Link Here 
1062
rdp_orders_process_memblt(struct rdp_orders* self, struct stream* s,
1073
rdp_orders_process_memblt(struct rdp_orders* self, struct stream* s,
1063
                          int present, int delta)
1074
                          int present, int delta)
1064
{
1075
{
1065
  struct rdp_bitmap* bitmap;
1076
  struct rdp_bitmap* bitmap = (struct rdp_bitmap *)NULL;
1066
  struct stream* rec_s;
1077
  struct stream* rec_s = (struct stream *)NULL;
1067
  char* bmpdata;
1078
  char* bmpdata = (char *)NULL;
1068
1079
1069
  if (present & 0x0001)
1080
  if (present & 0x0001)
1070
  {
1081
  {
 Lines 1200-1210    Link Here 
1200
rdp_orders_process_orders(struct rdp_orders* self, struct stream* s,
1211
rdp_orders_process_orders(struct rdp_orders* self, struct stream* s,
1201
                          int num_orders)
1212
                          int num_orders)
1202
{
1213
{
1203
  int processed;
1214
  int processed = 0;
1204
  int order_flags;
1215
  int order_flags = 0;
1205
  int size;
1216
  int size = 0;
1206
  int present;
1217
  int present = 0;
1207
  int delta;
1218
  int delta = 0;
1208
1219
1209
  processed = 0;
1220
  processed = 0;
1210
  while (processed < num_orders)
1221
  while (processed < num_orders)
 Lines 1304-1322    Link Here 
1304
/* returns pointer, it might return bmpdata if the data dosen't need to
1315
/* returns pointer, it might return bmpdata if the data dosen't need to
1305
   be converted, else it mallocs it.  The calling function must free
1316
   be converted, else it mallocs it.  The calling function must free
1306
   it if needed */
1317
   it if needed */
1307
char* APP_CC
1318
char * APP_CC
1308
rdp_orders_convert_bitmap(int in_bpp, int out_bpp, char* bmpdata,
1319
rdp_orders_convert_bitmap(int in_bpp, int out_bpp, char* bmpdata,
1309
                          int width, int height, int* palette)
1320
                          int width, int height, int* palette)
1310
{
1321
{
1311
  char* out;
1322
  char* out = (char *)NULL;
1312
  char* src;
1323
  char* src = (char *)NULL;
1313
  char* dst;
1324
  char* dst = (char *)NULL;
1314
  int i;
1325
  int i = 0;
1315
  int j;
1326
  int j = 0;
1316
  int red;
1327
  int red = 0;
1317
  int green;
1328
  int green = 0;
1318
  int blue;
1329
  int blue = 0;
1319
  int pixel;
1330
  int pixel = 0;
1320
1331
1321
  if ((in_bpp == 8) && (out_bpp == 8))
1332
  if ((in_bpp == 8) && (out_bpp == 8))
1322
  {
1333
  {
 Lines 1338-1343    Link Here 
1338
    }
1349
    }
1339
    return out;
1350
    return out;
1340
  }
1351
  }
1352
  if ((in_bpp == 8) && (out_bpp == 15))
1353
  {
1354
    out = (char*)g_malloc(width * height * 2, 0);
1355
    src = bmpdata;
1356
    dst = out;
1357
    for (i = 0; i < height; i++)
1358
    {
1359
      for (j = 0; j < width; j++)
1360
      {
1361
        pixel = *((tui8*)src);
1362
        pixel = palette[pixel];
1363
        SPLITCOLOR32(red, green, blue, pixel);
1364
        pixel = COLOR15(red, green, blue);
1365
        *((tui16*)dst) = pixel;
1366
        src++;
1367
        dst += 2;
1368
      }
1369
    }
1370
    return out;
1371
  }
1341
  if ((in_bpp == 8) && (out_bpp == 16))
1372
  if ((in_bpp == 8) && (out_bpp == 16))
1342
  {
1373
  {
1343
    out = (char*)g_malloc(width * height * 2, 0);
1374
    out = (char*)g_malloc(width * height * 2, 0);
 Lines 1372-1383    Link Here 
1372
        SPLITCOLOR32(red, green, blue, pixel);
1403
        SPLITCOLOR32(red, green, blue, pixel);
1373
        pixel = COLOR24RGB(red, green, blue);
1404
        pixel = COLOR24RGB(red, green, blue);
1374
        *((tui32*)dst) = pixel;
1405
        *((tui32*)dst) = pixel;
1375
        src++;;
1406
        src++;
1376
        dst += 4;
1407
        dst += 4;
1377
      }
1408
      }
1378
    }
1409
    }
1379
    return out;
1410
    return out;
1380
  }
1411
  }
1412
  if ((in_bpp == 15) && (out_bpp == 15))
1413
  {
1414
    return bmpdata;
1415
  }
1381
  if ((in_bpp == 15) && (out_bpp == 16))
1416
  if ((in_bpp == 15) && (out_bpp == 16))
1382
  {
1417
  {
1383
    out = (char*)g_malloc(width * height * 2, 0);
1418
    out = (char*)g_malloc(width * height * 2, 0);
 Lines 1469-1478    Link Here 
1469
int APP_CC
1504
int APP_CC
1470
rdp_orders_convert_color(int in_bpp, int out_bpp, int in_color, int* palette)
1505
rdp_orders_convert_color(int in_bpp, int out_bpp, int in_color, int* palette)
1471
{
1506
{
1472
  int pixel;
1507
  int pixel = 0;
1473
  int red;
1508
  int red = 0;
1474
  int green;
1509
  int green = 0;
1475
  int blue;
1510
  int blue = 0;
1476
1511
1477
  if ((in_bpp == 8) && (out_bpp == 8))
1512
  if ((in_bpp == 8) && (out_bpp == 8))
1478
  {
1513
  {
 Lines 1481-1486    Link Here 
1481
    pixel = COLOR8(red, green, blue);
1516
    pixel = COLOR8(red, green, blue);
1482
    return pixel;
1517
    return pixel;
1483
  }
1518
  }
1519
  if ((in_bpp == 8) && (out_bpp == 15))
1520
  {
1521
    pixel = palette[in_color];
1522
    SPLITCOLOR32(red, green, blue, pixel);
1523
    pixel = COLOR15(red, green, blue);
1524
    return pixel;
1525
  }
1484
  if ((in_bpp == 8) && (out_bpp == 16))
1526
  if ((in_bpp == 8) && (out_bpp == 16))
1485
  {
1527
  {
1486
    pixel = palette[in_color];
1528
    pixel = palette[in_color];
 Lines 1495-1500    Link Here 
1495
    pixel = COLOR24BGR(red, green, blue);
1537
    pixel = COLOR24BGR(red, green, blue);
1496
    return pixel;
1538
    return pixel;
1497
  }
1539
  }
1540
  if ((in_bpp == 8) && (out_bpp == 32))
1541
  {
1542
    pixel = palette[in_color];
1543
    SPLITCOLOR32(red, green, blue, pixel);
1544
    pixel = COLOR32BGR(red, green, blue);
1545
    return pixel;
1546
  }
1547
  if ((in_bpp == 15) && (out_bpp == 15))
1548
  {
1549
    return in_color;
1550
  }
1498
  if ((in_bpp == 15) && (out_bpp == 16))
1551
  if ((in_bpp == 15) && (out_bpp == 16))
1499
  {
1552
  {
1500
    pixel = in_color;
1553
    pixel = in_color;
 Lines 1509-1514    Link Here 
1509
    pixel = COLOR24BGR(red, green, blue);
1562
    pixel = COLOR24BGR(red, green, blue);
1510
    return pixel;
1563
    return pixel;
1511
  }
1564
  }
1565
  if ((in_bpp == 15) && (out_bpp == 32))
1566
  {
1567
    pixel = in_color;
1568
    SPLITCOLOR15(red, green, blue, pixel);
1569
    pixel = COLOR32BGR(red, green, blue);
1570
    return pixel;
1571
  }
1512
  if ((in_bpp == 16) && (out_bpp == 16))
1572
  if ((in_bpp == 16) && (out_bpp == 16))
1513
  {
1573
  {
1514
    return in_color;
1574
    return in_color;
 Lines 1520-1528    Link Here 
1520
    pixel = COLOR24BGR(red, green, blue);
1580
    pixel = COLOR24BGR(red, green, blue);
1521
    return pixel;
1581
    return pixel;
1522
  }
1582
  }
1583
  if ((in_bpp == 16) && (out_bpp == 32))
1584
  {
1585
    pixel = in_color;
1586
    SPLITCOLOR16(red, green, blue, pixel);
1587
    pixel = COLOR24BGR(red, green, blue);
1588
    return pixel;
1589
  }
1523
  if ((in_bpp == 24) && (out_bpp == 24))
1590
  if ((in_bpp == 24) && (out_bpp == 24))
1524
  {
1591
  {
1525
    return in_color;
1592
    return in_color;
1526
  }
1593
  }
1594
  if ((in_bpp == 24) && (out_bpp == 32))
1595
  {
1596
    pixel = in_color;
1597
    SPLITCOLOR32(red, green, blue, pixel);
1598
    pixel = COLOR32BGR(red, green, blue);
1599
    return pixel;
1600
  }
1601
  if ((in_bpp == 32) && (out_bpp == 32))
1602
  {
1603
    return in_color;
1604
  }
1527
  return 0;
1605
  return 0;
1528
}
1606
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/rdp/rdp_rdp.c (-41 / +49 lines)
 Lines 22-27    Link Here 
22
22
23
#include "rdp.h"
23
#include "rdp.h"
24
24
25
#ifndef NULL
26
#define NULL 0
27
#endif
28
25
/*****************************************************************************/
29
/*****************************************************************************/
26
struct rdp_rdp* APP_CC
30
struct rdp_rdp* APP_CC
27
rdp_rdp_create(struct mod* owner)
31
rdp_rdp_create(struct mod* owner)
 Lines 222-232    Link Here 
222
static int APP_CC
226
static int APP_CC
223
rdp_rdp_out_bmpcache_caps(struct rdp_rdp* self, struct stream* s)
227
rdp_rdp_out_bmpcache_caps(struct rdp_rdp* self, struct stream* s)
224
{
228
{
225
  int Bpp;
229
  int Bpp = 0;
226
230
227
  out_uint16_le(s, RDP_CAPSET_BMPCACHE);
231
  out_uint16_le(s, RDP_CAPSET_BMPCACHE);
228
  out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
232
  out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
229
  Bpp = (self->mod->rdp_bpp + 7) / 8;
233
  Bpp = (self->mod->rdp_bpp == 32) ? 3 : (self->mod->rdp_bpp + 7) / 8;
230
  out_uint8s(s, 24); /* unused */
234
  out_uint8s(s, 24); /* unused */
231
  out_uint16_le(s, 0x258); /* entries */
235
  out_uint16_le(s, 0x258); /* entries */
232
  out_uint16_le(s, 0x100 * Bpp); /* max cell size */
236
  out_uint16_le(s, 0x100 * Bpp); /* max cell size */
 Lines 508-533    Link Here 
508
static void APP_CC
512
static void APP_CC
509
rdp_rdp_process_bitmap_updates(struct rdp_rdp* self, struct stream* s)
513
rdp_rdp_process_bitmap_updates(struct rdp_rdp* self, struct stream* s)
510
{
514
{
511
  int num_updates;
515
  int num_updates = 0;
512
  int left;
516
  int left = 0;
513
  int top;
517
  int top = 0;
514
  int right;
518
  int right = 0;
515
  int bottom;
519
  int bottom = 0;
516
  int width;
520
  int width = 0;
517
  int height;
521
  int height = 0;
518
  int cx;
522
  int cx = 0;
519
  int cy;
523
  int cy = 0;
520
  int bpp;
524
  int bpp = 0;
521
  int Bpp;
525
  int Bpp = 0;
522
  int compress;
526
  int compress = 0;
523
  int bufsize;
527
  int bufsize = 0;
524
  int size;
528
  int size = 0;
525
  int i;
529
  int i = 0;
526
  int x;
530
  int x = 0;
527
  int y;
531
  int y = 0;
528
  char* data;
532
  char* data = NULL;
529
  char* bmpdata0;
533
  char* bmpdata0 = NULL;
530
  char* bmpdata1;
534
  char* bmpdata1 = NULL;
531
535
532
  in_uint16_le(s, num_updates);
536
  in_uint16_le(s, num_updates);
533
  for (i = 0; i < num_updates; i++)
537
  for (i = 0; i < num_updates; i++)
 Lines 539-545    Link Here 
539
    in_uint16_le(s, width);
543
    in_uint16_le(s, width);
540
    in_uint16_le(s, height);
544
    in_uint16_le(s, height);
541
    in_uint16_le(s, bpp);
545
    in_uint16_le(s, bpp);
542
    Bpp = (bpp + 7) / 8;
546
    Bpp = (bpp == 32) ? 3 : (bpp + 7) / 8;
543
    in_uint16_le(s, compress);
547
    in_uint16_le(s, compress);
544
    in_uint16_le(s, bufsize);
548
    in_uint16_le(s, bufsize);
545
    cx = (right - left) + 1;
549
    cx = (right - left) + 1;
 Lines 869-874    Link Here 
869
{
873
{
870
  int data_pdu_type;
874
  int data_pdu_type;
871
  int ctype;
875
  int ctype;
876
  int clen;
872
  int len;
877
  int len;
873
  int rv;
878
  int rv;
874
879
 Lines 877-883    Link Here 
877
  in_uint16_le(s, len);
882
  in_uint16_le(s, len);
878
  in_uint8(s, data_pdu_type);
883
  in_uint8(s, data_pdu_type);
879
  in_uint8(s, ctype);
884
  in_uint8(s, ctype);
880
  in_uint8s(s, 2); /* clen */
885
  in_uint16_le(s, clen);
886
  clen -= 18;
881
  switch (data_pdu_type)
887
  switch (data_pdu_type)
882
  {
888
  {
883
    case RDP_DATA_PDU_UPDATE:
889
    case RDP_DATA_PDU_UPDATE:
 Lines 915-923    Link Here 
915
static void APP_CC
921
static void APP_CC
916
rdp_rdp_process_bitmap_caps(struct rdp_rdp* self, struct stream* s)
922
rdp_rdp_process_bitmap_caps(struct rdp_rdp* self, struct stream* s)
917
{
923
{
918
  int width;
924
  int width = 0;
919
  int height;
925
  int height = 0;
920
  int bpp;
926
  int bpp = 0;
921
927
922
  in_uint16_le(s, bpp);
928
  in_uint16_le(s, bpp);
923
  in_uint8s(s, 6);
929
  in_uint8s(s, 6);
 Lines 933-944    Link Here 
933
static int APP_CC
939
static int APP_CC
934
rdp_rdp_process_server_caps(struct rdp_rdp* self, struct stream* s, int len)
940
rdp_rdp_process_server_caps(struct rdp_rdp* self, struct stream* s, int len)
935
{
941
{
936
  int n;
942
  int n = 0;
937
  int ncapsets;
943
  int ncapsets = 0;
938
  int capset_type;
944
  int capset_type = 0;
939
  int capset_length;
945
  int capset_length = 0;
940
  char* next;
946
  char* next = NULL;
941
  char* start;
947
  char* start = NULL;
942
948
943
  start = s->p;
949
  start = s->p;
944
  in_uint16_le(s, ncapsets);
950
  in_uint16_le(s, ncapsets);
 Lines 1035-1043    Link Here 
1035
int APP_CC
1041
int APP_CC
1036
rdp_rdp_process_demand_active(struct rdp_rdp* self, struct stream* s)
1042
rdp_rdp_process_demand_active(struct rdp_rdp* self, struct stream* s)
1037
{
1043
{
1038
  int type;
1044
  int type = 0;
1039
  int len_src_descriptor;
1045
  int len_src_descriptor = 0;
1040
  int len_combined_caps;
1046
  int len_combined_caps = 0;
1041
1047
1042
  in_uint32_le(s, self->share_id);
1048
  in_uint32_le(s, self->share_id);
1043
  in_uint16_le(s, len_src_descriptor);
1049
  in_uint16_le(s, len_src_descriptor);
 Lines 1064-1072    Link Here 
1064
rdp_rec_check_file(struct rdp_rdp* self)
1070
rdp_rec_check_file(struct rdp_rdp* self)
1065
{
1071
{
1066
  char file_name[256];
1072
  char file_name[256];
1067
  int index;
1073
  int index = 0;
1068
  int len;
1074
  int len = 0;
1069
  struct stream* s;
1075
  struct stream* s = (struct stream *)NULL;
1076
1077
  g_memset(file_name,0,sizeof(char) * 256);
1070
1078
1071
  if (self->rec_fd == 0)
1079
  if (self->rec_fd == 0)
1072
  {
1080
  {
 Lines 1098-1105    Link Here 
1098
int APP_CC
1106
int APP_CC
1099
rdp_rec_write_item(struct rdp_rdp* self, struct stream* s)
1107
rdp_rec_write_item(struct rdp_rdp* self, struct stream* s)
1100
{
1108
{
1101
  int len;
1109
  int len = 0;
1102
  int time;
1110
  int time = 0;
1103
1111
1104
  if (self->rec_fd == 0)
1112
  if (self->rec_fd == 0)
1105
  {
1113
  {
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/alsa.c (+283 lines)
Line 0    Link Here 
1
#include "alsa.h"
2
#include "dbg.h"
3
4
alsa * g_alsa = (alsa *)NULL;
5
6
static int APP_CC g_alsa_setup_fifo(struct _alsa *, const char *);
7
8
/*****************************************************/
9
int APP_CC
10
g_alsa_init(void) {
11
  int rv = 0;
12
  void * g_alsa_handle = (void *)NULL;
13
  g_alsa_handle = dlopen("libasound.so.2", RTLD_LAZY | RTLD_GLOBAL);
14
  if (g_alsa_handle == NULL) {
15
    rv = -1;
16
  }
17
  else {
18
    /* instantiate the alsa class: */
19
    g_alsa = (alsa *)g_malloc(sizeof(alsa),1);
20
    g_alsa->hLocal = g_alsa_handle;
21
    g_alsa->hALSA = dlopen(0, RTLD_LAZY);
22
23
    g_alsa->fifo = -1;
24
25
    /* associate class methods with their corresponding libasound2 functions: */
26
    g_alsa->snd_pcm_file_open = dlsym(g_alsa->hALSA,"snd_pcm_file_open");
27
    g_alsa->snd_pcm_dmix_open = dlsym(g_alsa->hALSA,"snd_pcm_dmix_open");
28
    g_alsa->snd_pcm_null_open = dlsym(g_alsa->hALSA,"snd_pcm_null_open");
29
    g_alsa->snd_pcm_set_params = dlsym(g_alsa->hALSA,"snd_pcm_set_params");
30
    g_alsa->snd_pcm_open = dlsym(g_alsa->hALSA,"snd_pcm_open");
31
    g_alsa->snd_pcm_open_lconf = dlsym(g_alsa->hALSA,"snd_pcm_open_lconf");
32
    g_alsa->snd_pcm_close = dlsym(g_alsa->hALSA,"snd_pcm_close");
33
    g_alsa->snd_pcm_name = dlsym(g_alsa->hALSA,"snd_pcm_name");
34
    g_alsa->snd_pcm_type = dlsym(g_alsa->hALSA,"snd_pcm_type");
35
    g_alsa->snd_pcm_stream = dlsym(g_alsa->hALSA,"snd_pcm_stream");
36
    g_alsa->snd_pcm_poll_descriptors_count = dlsym(g_alsa->hALSA,"snd_pcm_poll_descriptors_count");
37
    g_alsa->snd_pcm_poll_descriptors = dlsym(g_alsa->hALSA,"snd_pcm_poll_descriptors");
38
    g_alsa->snd_pcm_poll_descriptors_revents = dlsym(g_alsa->hALSA,"snd_pcm_poll_descriptors_revents");
39
    g_alsa->snd_pcm_nonblock = dlsym(g_alsa->hALSA,"snd_pcm_nonblock");
40
    g_alsa->snd_pcm_access_mask_none = dlsym(g_alsa->hALSA,"snd_pcm_access_mask_none");
41
    g_alsa->snd_pcm_access_mask_any = dlsym(g_alsa->hALSA,"snd_pcm_access_mask_any");
42
    g_alsa->snd_pcm_access_mask_empty = dlsym(g_alsa->hALSA,"snd_pcm_access_mask_empty");
43
    g_alsa->snd_pcm_access_mask_set = dlsym(g_alsa->hALSA,"snd_pcm_access_mask_set");
44
    g_alsa->snd_pcm_access_mask_reset = dlsym(g_alsa->hALSA,"snd_pcm_access_mask_reset");
45
    g_alsa->snd_pcm_format_mask_none = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_none");
46
    g_alsa->snd_pcm_format_mask_any = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_any");
47
    g_alsa->snd_pcm_format_mask_empty = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_empty");
48
    g_alsa->snd_pcm_format_mask_set = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_set");
49
    g_alsa->snd_pcm_format_mask_reset = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_reset");
50
    g_alsa->snd_pcm_format_mask_malloc = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_malloc");
51
    g_alsa->snd_pcm_format_mask_free = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_free");
52
    g_alsa->snd_pcm_format_mask_copy = dlsym(g_alsa->hALSA,"snd_pcm_format_mask_copy");
53
    g_alsa->snd_pcm_state = dlsym(g_alsa->hALSA,"snd_pcm_state");
54
    g_alsa->snd_pcm_prepare = dlsym(g_alsa->hALSA,"snd_pcm_prepare");
55
    g_alsa->snd_pcm_reset = dlsym(g_alsa->hALSA,"snd_pcm_reset");
56
    g_alsa->snd_pcm_start = dlsym(g_alsa->hALSA,"snd_pcm_start");
57
    g_alsa->snd_pcm_drop = dlsym(g_alsa->hALSA,"snd_pcm_drop");
58
    g_alsa->snd_pcm_drain = dlsym(g_alsa->hALSA,"snd_pcm_drain");
59
    g_alsa->snd_pcm_pause = dlsym(g_alsa->hALSA,"snd_pcm_pause");
60
    g_alsa->snd_pcm_resume = dlsym(g_alsa->hALSA,"snd_pcm_resume");
61
    g_alsa->snd_pcm_delay = dlsym(g_alsa->hALSA,"snd_pcm_delay");
62
    g_alsa->snd_pcm_writei = dlsym(g_alsa->hALSA,"snd_pcm_writei");
63
    g_alsa->snd_pcm_writen = dlsym(g_alsa->hALSA,"snd_pcm_writen");
64
    g_alsa->snd_pcm_readi = dlsym(g_alsa->hALSA,"snd_pcm_readi");
65
    g_alsa->snd_pcm_readn = dlsym(g_alsa->hALSA,"snd_pcm_readn");
66
    g_alsa->snd_pcm_link = dlsym(g_alsa->hALSA,"snd_pcm_link");
67
    g_alsa->snd_pcm_unlink = dlsym(g_alsa->hALSA,"snd_pcm_unlink");
68
    g_alsa->snd_pcm_wait = dlsym(g_alsa->hALSA,"snd_pcm_wait");
69
    g_alsa->snd_pcm_avail_update = dlsym(g_alsa->hALSA,"snd_pcm_avail_update");
70
    g_alsa->snd_pcm_avail = dlsym(g_alsa->hALSA,"snd_pcm_avail");
71
    g_alsa->snd_pcm_bytes_to_samples = dlsym(g_alsa->hALSA,"snd_pcm_bytes_to_samples");
72
    g_alsa->snd_pcm_samples_to_bytes = dlsym(g_alsa->hALSA,"snd_pcm_samples_to_bytes");
73
    g_alsa->snd_async_add_pcm_handler = dlsym(g_alsa->hALSA,"snd_async_add_pcm_handler");
74
    g_alsa->snd_async_handler_get_pcm = dlsym(g_alsa->hALSA,"snd_async_handler_get_pcm");
75
    g_alsa->snd_pcm_hw_params_can_pause = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_can_pause");
76
    g_alsa->snd_pcm_hw_params_can_resume = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_can_resume");
77
    g_alsa->snd_pcm_info = dlsym(g_alsa->hALSA,"snd_pcm_info");
78
    g_alsa->snd_pcm_hw_params_current = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_current");
79
    g_alsa->snd_pcm_info_sizeof = dlsym(g_alsa->hALSA,"snd_pcm_info_sizeof");
80
    g_alsa->snd_pcm_info_malloc = dlsym(g_alsa->hALSA,"snd_pcm_info_malloc");
81
    g_alsa->snd_pcm_info_free = dlsym(g_alsa->hALSA,"snd_pcm_info_free");
82
    g_alsa->snd_pcm_info_copy = dlsym(g_alsa->hALSA,"snd_pcm_info_copy");
83
    g_alsa->snd_pcm_info_get_device = dlsym(g_alsa->hALSA,"snd_pcm_info_get_device");
84
    g_alsa->snd_pcm_info_get_subdevice = dlsym(g_alsa->hALSA,"snd_pcm_info_get_subdevice");
85
    g_alsa->snd_pcm_info_get_stream = dlsym(g_alsa->hALSA,"snd_pcm_info_get_stream");
86
    g_alsa->snd_pcm_info_get_card = dlsym(g_alsa->hALSA,"snd_pcm_info_get_card");
87
    g_alsa->snd_pcm_info_get_id = dlsym(g_alsa->hALSA,"snd_pcm_info_get_id");
88
    g_alsa->snd_pcm_info_get_name = dlsym(g_alsa->hALSA,"snd_pcm_info_get_name");
89
    g_alsa->snd_pcm_info_get_subdevice_name = dlsym(g_alsa->hALSA,"snd_pcm_info_get_subdevice_name");
90
    g_alsa->snd_pcm_info_get_class = dlsym(g_alsa->hALSA,"snd_pcm_info_get_class");
91
    g_alsa->snd_pcm_info_get_subclass = dlsym(g_alsa->hALSA,"snd_pcm_info_get_subclass");
92
    g_alsa->snd_pcm_info_get_subdevices_count = dlsym(g_alsa->hALSA,"snd_pcm_info_get_subdevices_count");
93
    g_alsa->snd_pcm_info_get_subdevices_avail = dlsym(g_alsa->hALSA,"snd_pcm_info_get_subdevices_avail");
94
    g_alsa->snd_pcm_info_get_sync = dlsym(g_alsa->hALSA,"snd_pcm_info_get_sync");
95
    g_alsa->snd_pcm_info_set_device = dlsym(g_alsa->hALSA,"snd_pcm_info_set_device");
96
    g_alsa->snd_pcm_info_set_subdevice = dlsym(g_alsa->hALSA,"snd_pcm_info_set_subdevice");
97
    g_alsa->snd_pcm_info_set_stream = dlsym(g_alsa->hALSA,"snd_pcm_info_set_stream");
98
    g_alsa->snd_pcm_type_name = dlsym(g_alsa->hALSA,"snd_pcm_type_name");
99
    g_alsa->snd_pcm_stream_name = dlsym(g_alsa->hALSA,"snd_pcm_stream_name");
100
    g_alsa->snd_pcm_access_name = dlsym(g_alsa->hALSA,"snd_pcm_access_name");
101
    g_alsa->snd_pcm_format_name = dlsym(g_alsa->hALSA,"snd_pcm_format_name");
102
    g_alsa->snd_pcm_format_description = dlsym(g_alsa->hALSA,"snd_pcm_format_description");
103
    g_alsa->snd_pcm_subformat_name = dlsym(g_alsa->hALSA,"snd_pcm_subformat_name");
104
    g_alsa->snd_pcm_subformat_description = dlsym(g_alsa->hALSA,"snd_pcm_subformat_description");
105
    g_alsa->snd_pcm_format_value = dlsym(g_alsa->hALSA,"snd_pcm_format_value");
106
    g_alsa->snd_pcm_tstamp_mode_name = dlsym(g_alsa->hALSA,"snd_pcm_tstamp_mode_name");
107
    g_alsa->snd_pcm_state_name = dlsym(g_alsa->hALSA,"snd_pcm_state_name");
108
    g_alsa->snd_pcm_dump = dlsym(g_alsa->hALSA,"snd_pcm_dump");
109
    g_alsa->snd_pcm_dump_hw_setup = dlsym(g_alsa->hALSA,"snd_pcm_dump_hw_setup");
110
    g_alsa->snd_pcm_dump_sw_setup = dlsym(g_alsa->hALSA,"snd_pcm_dump_sw_setup");
111
    g_alsa->snd_pcm_dump_setup = dlsym(g_alsa->hALSA,"snd_pcm_dump_setup");
112
    g_alsa->snd_pcm_hw_params_dump = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_dump");
113
    g_alsa->snd_pcm_sw_params_dump = dlsym(g_alsa->hALSA,"snd_pcm_sw_params_dump");
114
    g_alsa->snd_pcm_status_dump = dlsym(g_alsa->hALSA,"snd_pcm_status_dump");
115
    g_alsa->snd_pcm_hw_params_any = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_any");
116
    g_alsa->snd_pcm_hw_params_get_sbits = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_sbits");
117
    g_alsa->snd_pcm_hw_params_sizeof = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_sizeof");
118
    g_alsa->snd_pcm_hw_params_malloc = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_malloc");
119
    g_alsa->snd_pcm_hw_params_free = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_free");
120
    g_alsa->snd_pcm_hw_params_copy = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_copy");
121
    g_alsa->snd_pcm_hw_params_set_access = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_access");
122
    g_alsa->snd_pcm_hw_params_get_access = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_access");
123
    g_alsa->snd_pcm_hw_params_set_access_mask = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_access_mask");
124
    g_alsa->snd_pcm_hw_params_get_access_mask = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_access_mask");
125
    g_alsa->snd_pcm_hw_params_get_format = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_format");
126
    g_alsa->snd_pcm_hw_params_set_format = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_format");
127
    g_alsa->snd_pcm_hw_params_set_format_mask = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_format_mask");
128
    g_alsa->snd_pcm_hw_params_get_format_mask = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_format_mask");
129
    g_alsa->snd_pcm_hw_params_get_subformat = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_subformat");
130
    g_alsa->snd_pcm_hw_params_set_subformat = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_subformat");
131
    g_alsa->snd_pcm_hw_params_set_subformat_mask = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_subformat_mask");
132
    g_alsa->snd_pcm_hw_params_get_subformat_mask = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_subformat_mask");
133
    g_alsa->snd_pcm_hw_params_get_rate = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_rate");
134
    g_alsa->snd_pcm_hw_params_set_rate = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_rate");
135
    g_alsa->snd_pcm_hw_params_get_rate_min = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_rate_min");
136
    g_alsa->snd_pcm_hw_params_get_rate_max = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_rate_max");
137
    g_alsa->snd_pcm_hw_params_set_rate_min = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_rate_min");
138
    g_alsa->snd_pcm_hw_params_set_rate_max = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_rate_max");
139
    g_alsa->snd_pcm_hw_params_set_rate_minmax = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_rate_minmax");
140
    g_alsa->snd_pcm_hw_params_set_rate_near = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_rate_near");
141
    g_alsa->snd_pcm_hw_params_set_rate_resample = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_rate_resample");
142
    g_alsa->snd_pcm_hw_params_get_rate_resample = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_rate_resample");
143
    g_alsa->snd_pcm_hw_params_get_channels = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_channels");
144
    g_alsa->snd_pcm_hw_params_set_channels = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_set_channels");
145
    g_alsa->snd_pcm_hw_params_get_min_align = dlsym(g_alsa->hALSA,"snd_pcm_hw_params_get_min_align");
146
    g_alsa->snd_config_make_compound = dlsym(g_alsa->hALSA,"snd_config_make_compound");
147
    g_alsa->snd_config_make = dlsym(g_alsa->hALSA,"snd_config_make");
148
    g_alsa->snd_config_make_string = dlsym(g_alsa->hALSA,"snd_config_make_string");
149
    g_alsa->snd_config_make_integer = dlsym(g_alsa->hALSA,"snd_config_make_integer");
150
    g_alsa->snd_config_make_integer64 = dlsym(g_alsa->hALSA,"snd_config_make_integer64");
151
    g_alsa->snd_config_make_real = dlsym(g_alsa->hALSA,"snd_config_make_real");
152
    g_alsa->snd_config_make_pointer = dlsym(g_alsa->hALSA,"snd_config_make_pointer");
153
    g_alsa->snd_config_imake_string = dlsym(g_alsa->hALSA,"snd_config_imake_string");
154
    g_alsa->snd_config_imake_integer = dlsym(g_alsa->hALSA,"snd_config_imake_integer");
155
    g_alsa->snd_config_imake_integer64 = dlsym(g_alsa->hALSA,"snd_config_imake_integer64");
156
    g_alsa->snd_config_imake_real = dlsym(g_alsa->hALSA,"snd_config_imake_real");
157
    g_alsa->snd_config_imake_pointer = dlsym(g_alsa->hALSA,"snd_config_imake_pointer");
158
    g_alsa->snd_config_load = dlsym(g_alsa->hALSA,"snd_config_load");
159
    g_alsa->snd_config_top = dlsym(g_alsa->hALSA,"snd_config_top");
160
    g_alsa->snd_config_load_override = dlsym(g_alsa->hALSA,"snd_config_load_override");
161
    g_alsa->snd_config_save = dlsym(g_alsa->hALSA,"snd_config_save");
162
    g_alsa->snd_config_update = dlsym(g_alsa->hALSA,"snd_config_update");
163
    g_alsa->snd_config_search = dlsym(g_alsa->hALSA,"snd_config_search");
164
    g_alsa->snd_config_searchv = dlsym(g_alsa->hALSA,"snd_config_searchv");
165
    g_alsa->snd_config_search_definition = dlsym(g_alsa->hALSA,"snd_config_search_definition");
166
    g_alsa->snd_config_expand = dlsym(g_alsa->hALSA,"snd_config_expand");
167
    g_alsa->snd_config_add = dlsym(g_alsa->hALSA,"snd_config_add");
168
    g_alsa->snd_config_delete = dlsym(g_alsa->hALSA,"snd_config_delete");
169
    g_alsa->snd_config_delete_compound_members = dlsym(g_alsa->hALSA,"snd_config_delete_compound_members");
170
    g_alsa->snd_config_copy = dlsym(g_alsa->hALSA,"snd_config_copy");
171
    g_alsa->snd_config_get_type = dlsym(g_alsa->hALSA,"snd_config_get_type");
172
    g_alsa->snd_config_set_id = dlsym(g_alsa->hALSA,"snd_config_set_id");
173
    g_alsa->snd_config_set_integer = dlsym(g_alsa->hALSA,"snd_config_set_integer");
174
    g_alsa->snd_config_set_integer64 = dlsym(g_alsa->hALSA,"snd_config_set_integer64");
175
    g_alsa->snd_config_set_real = dlsym(g_alsa->hALSA,"snd_config_set_real");
176
    g_alsa->snd_config_set_string = dlsym(g_alsa->hALSA,"snd_config_set_string");
177
    g_alsa->snd_config_set_ascii = dlsym(g_alsa->hALSA,"snd_config_set_ascii");
178
    g_alsa->snd_config_set_pointer = dlsym(g_alsa->hALSA,"snd_config_set_pointer");
179
    g_alsa->snd_config_get_id = dlsym(g_alsa->hALSA,"snd_config_get_id");
180
    g_alsa->snd_config_get_integer = dlsym(g_alsa->hALSA,"snd_config_get_integer");
181
    g_alsa->snd_config_get_integer64 = dlsym(g_alsa->hALSA,"snd_config_get_integer64");
182
    g_alsa->snd_config_get_real = dlsym(g_alsa->hALSA,"snd_config_get_real");
183
    g_alsa->snd_config_get_ireal = dlsym(g_alsa->hALSA,"snd_config_get_ireal");
184
    g_alsa->snd_config_get_string = dlsym(g_alsa->hALSA,"snd_config_get_string");
185
    g_alsa->snd_config_get_ascii = dlsym(g_alsa->hALSA,"snd_config_get_ascii");
186
    g_alsa->snd_config_get_pointer = dlsym(g_alsa->hALSA,"snd_config_get_pointer");
187
    g_alsa->snd_config_iterator_first = dlsym(g_alsa->hALSA,"snd_config_iterator_first");
188
    g_alsa->snd_config_iterator_next = dlsym(g_alsa->hALSA,"snd_config_iterator_next");
189
    g_alsa->snd_config_iterator_end = dlsym(g_alsa->hALSA,"snd_config_iterator_end");
190
    g_alsa->snd_config_iterator_entry = dlsym(g_alsa->hALSA,"snd_config_iterator_entry");
191
    g_alsa->snd_config_test_id = dlsym(g_alsa->hALSA,"snd_config_test_id");
192
    g_alsa->snd_names_list = dlsym(g_alsa->hALSA,"snd_names_list");
193
    g_alsa->snd_config_get_bool_ascii = dlsym(g_alsa->hALSA,"snd_config_get_bool_ascii");
194
    g_alsa->snd_config_get_bool = dlsym(g_alsa->hALSA,"snd_config_get_bool");
195
    g_alsa->snd_config_get_ctl_iface_ascii = dlsym(g_alsa->hALSA,"snd_config_get_ctl_iface_ascii");
196
    g_alsa->snd_config_get_ctl_iface = dlsym(g_alsa->hALSA,"snd_config_get_ctl_iface");
197
    g_alsa->snd_config = dlsym(g_alsa->hALSA,"snd_config");
198
    g_alsa->setup_fifo = &g_alsa_setup_fifo;
199
  }
200
  return rv;
201
}
202
203
204
/*****************************************************/
205
int APP_CC
206
g_alsa_deinit(void) {
207
  int rv = 0;
208
  if (g_alsa != NULL) {
209
    if (g_alsa->pcm != NULL) {
210
      g_alsa->snd_pcm_close(g_alsa->pcm);
211
      g_alsa->pcm = NULL;
212
    }
213
    if (g_alsa->fifo != -1) {
214
      close(g_alsa->fifo);
215
      g_alsa->fifo = -1;
216
    }
217
    dlclose(g_alsa->hLocal);
218
    dlclose(g_alsa->hALSA);
219
    g_memset(g_alsa,0,sizeof(alsa));
220
    //g_free(g_alsa);
221
    g_alsa = (alsa *)NULL;
222
  }
223
  return rv;
224
}
225
226
227
/*****************************************************/
228
static int APP_CC
229
g_alsa_setup_fifo(struct _alsa * self, const char * fpath) {
230
  int rv = 0;
231
  snd_config_t * top_pcm_cfg = (snd_config_t *)NULL;
232
  snd_config_t * null_cfg = (snd_config_t *)NULL;
233
  snd_config_t * pcm_cfg = (snd_config_t *)NULL;
234
  snd_config_t * slave_cfg = (snd_config_t *)NULL;
235
  snd_config_t * tmp = (snd_config_t *)NULL;
236
237
  MDBGLOG("sound","g_alsa_setup_fifo: fpath = %s\0",fpath);
238
239
  if (fpath != NULL && g_strlen(fpath) > 0) {
240
    rv = mkfifo(fpath, 0644);
241
    rv = 0;
242
  }
243
244
  if (rv > -1 && 1==2) {
245
    self->snd_config_search(self->snd_config,"pcm",&top_pcm_cfg);
246
    self->snd_config_make_compound(&pcm_cfg,"xrdp",0);
247
    self->snd_config_imake_string(&tmp,"type","file");
248
    self->snd_config_add(pcm_cfg,tmp);
249
    self->snd_config_imake_string(&tmp,"file",AUDIO_FIFO_PATH);
250
    self->snd_config_add(pcm_cfg,tmp);
251
    self->snd_config_make_compound(&null_cfg,"pcm",0);
252
    self->snd_config_imake_string(&tmp,"type","null");
253
    self->snd_config_add(null_cfg,tmp);
254
    self->snd_config_make_compound(&slave_cfg,"slave",0);
255
    self->snd_config_add(slave_cfg,null_cfg);
256
    self->snd_config_add(pcm_cfg,slave_cfg);
257
    //self->snd_config_add(top_pcm_cfg,pcm_cfg);
258
    //self->snd_config_add(self->snd_config,pcm_cfg);
259
    //DBGLOG("sound","hereE");
260
    //self->snd_config_imake_string(&tmp,"main_playback","xrdp");
261
    //DBGLOG("sound","hereF");
262
    //self->snd_config_add(top_pcm_cfg,tmp);
263
    MDBGLOG("sound","hereG: self->snd_config = %d",(int)self->snd_config);
264
  }
265
266
  if (1==2) {
267
    if (rv > -1) {
268
      rv = self->snd_pcm_null_open(&(self->pcm_null),"xrdp_null",SND_PCM_STREAM_PLAYBACK,1);
269
      if (rv > -1) {
270
        rv = self->snd_pcm_file_open(&(self->pcm),"xrdp",fpath,-1,NULL,-1,0,"raw",0644,self->pcm_null,1);
271
      }
272
    }
273
  }
274
275
  if (rv < 0) {
276
    close(self->fifo);
277
    unlink(fpath);
278
  }
279
280
  MDBGLOG("sound","g_alsa_setup_fifo: done (rv = %d)\0",rv);
281
282
  return rv;
283
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/alsa.h (+262 lines)
Line 0    Link Here 
1
#ifndef _XRDP_ALSA_
2
#define _XRDP_ALSA_
3
4
#include <stdio.h>
5
#include <fcntl.h>
6
#include <unistd.h>
7
#include <pwd.h>
8
#include <grp.h>
9
#include <string.h>
10
#include <dlfcn.h>
11
#include <alsa/asoundef.h>
12
#include <alsa/asoundlib.h>
13
#include <alsa/conf.h>
14
#include <alsa/error.h>
15
#include <alsa/global.h>
16
#include <alsa/hwdep.h>
17
#include <alsa/control.h>
18
#include <alsa/control_external.h>
19
#include <alsa/input.h>
20
#include <alsa/mixer.h>
21
#include <alsa/output.h>
22
#include <alsa/pcm.h>
23
#include <alsa/pcm_plugin.h>
24
#include <alsa/pcm_extplug.h>
25
#include <alsa/pcm_external.h>
26
#include <alsa/pcm_ioplug.h>
27
#include <alsa/seq.h>
28
#include <alsa/seq_event.h>
29
#include <alsa/timer.h>
30
#include <alsa/version.h>
31
#include "defines.h"
32
#include "arch.h"
33
#include "os_calls.h"
34
35
struct snd_pcm_direct_open_conf;
36
struct slave_params;
37
typedef struct snd_pcm_direct_open_conf snd_pcm_direct_open_conf_t;
38
typedef struct slave_params slave_params_t;
39
40
/*					*/
41
/*	pseudo-class:	"alsa"		*/
42
typedef struct _alsa {
43
	/*	members:		*/
44
	void *			hALSA;
45
	void *			hLocal;
46
	char *			device;		/* playback device */
47
	snd_pcm_format_t 	format;		/* = SND_PCM_FORMAT_S16 */
48
	unsigned int		rate;
49
	unsigned int		channels;
50
	unsigned int		buffer_time;
51
	int			resample;
52
	snd_pcm_sframes_t	buffer_size;
53
	snd_output_t *		output;
54
	int			fifo;
55
	snd_pcm_t *		pcm;
56
	snd_pcm_t *		pcm_null;
57
58
	/*	mapped members:	*/
59
	snd_config_t *		snd_config;
60
61
	/*	mapped methods:			*/
62
	int			(*snd_pcm_file_open)(snd_pcm_t **, const char *, const char *, int, const char *, int, int, const char *, int, snd_pcm_t *, int);
63
	int			(*snd_pcm_dmix_open)(snd_pcm_t **, const char *, snd_pcm_direct_open_conf_t *, slave_params_t *, snd_config_t *, snd_config_t *, snd_pcm_stream_t, int);
64
	int			(*snd_pcm_null_open)(snd_pcm_t **, const char *, snd_pcm_stream_t, int);
65
	int			(*snd_pcm_set_params)(snd_pcm_t *, snd_pcm_format_t, snd_pcm_access_t, unsigned int, unsigned int, int, unsigned int);
66
	int			(*snd_pcm_open)(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);
67
	int			(*snd_pcm_open_lconf)(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode, snd_config_t *lconf);
68
	int			(*snd_pcm_close)(snd_pcm_t *pcm);
69
	const char *		(*snd_pcm_name)(snd_pcm_t *pcm);
70
	snd_pcm_type_t		(*snd_pcm_type)(snd_pcm_t *pcm);
71
	snd_pcm_stream_t	(*snd_pcm_stream)(snd_pcm_t *pcm);
72
	int			(*snd_pcm_poll_descriptors_count)(snd_pcm_t *pcm);
73
	int			(*snd_pcm_poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
74
	int			(*snd_pcm_poll_descriptors_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
75
	int			(*snd_pcm_nonblock)(snd_pcm_t *pcm, int nonblock);
76
	int			(*snd_pcm_info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
77
	int			(*snd_pcm_hw_params_current)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
78
	long			(*snd_pcm_bytes_to_samples)(snd_pcm_t *pcm, ssize_t bytes);
79
	ssize_t			(*snd_pcm_samples_to_bytes)(snd_pcm_t *pcm, long samples);
80
	int			(*snd_async_add_pcm_handler)(snd_async_handler_t **handler, snd_pcm_t *pcm, snd_async_callback_t callback, void *private_data);
81
	snd_pcm_t *		(*snd_async_handler_get_pcm)(snd_async_handler_t *handler);
82
	int			(*snd_pcm_hw_params_can_pause)(const snd_pcm_hw_params_t *params);
83
	int			(*snd_pcm_hw_params_can_resume)(const snd_pcm_hw_params_t *params);
84
	snd_pcm_state_t		(*snd_pcm_state)(snd_pcm_t *pcm);
85
	int			(*snd_pcm_prepare)(snd_pcm_t *pcm);
86
	int			(*snd_pcm_reset)(snd_pcm_t *pcm);
87
	int			(*snd_pcm_start)(snd_pcm_t *pcm);
88
	int			(*snd_pcm_drop)(snd_pcm_t *pcm);
89
	int			(*snd_pcm_drain)(snd_pcm_t *pcm);
90
	int			(*snd_pcm_pause)(snd_pcm_t *pcm, int enable);
91
	int			(*snd_pcm_resume)(snd_pcm_t *pcm);
92
	int			(*snd_pcm_delay)(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
93
	snd_pcm_sframes_t	(*snd_pcm_writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
94
	snd_pcm_sframes_t	(*snd_pcm_writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
95
	snd_pcm_sframes_t	(*snd_pcm_readi)(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
96
	snd_pcm_sframes_t	(*snd_pcm_readn)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
97
	int			(*snd_pcm_link)(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
98
	int			(*snd_pcm_unlink)(snd_pcm_t *pcm);
99
	int			(*snd_pcm_wait)(snd_pcm_t *pcm, int timeout);
100
	snd_pcm_sframes_t	(*snd_pcm_avail_update)(snd_pcm_t *pcm);
101
	snd_pcm_sframes_t	(*snd_pcm_avail)(snd_pcm_t *pcm);
102
	
103
104
	/*	streams		*/
105
	size_t			(*snd_pcm_info_sizeof)(void);
106
	int			(*snd_pcm_info_malloc)(snd_pcm_info_t **ptr);
107
	void			(*snd_pcm_info_free)(snd_pcm_info_t *obj);
108
	void			(*snd_pcm_info_copy)(snd_pcm_info_t *dst, const snd_pcm_info_t *src);
109
	unsigned int		(*snd_pcm_info_get_device)(const snd_pcm_info_t *obj);
110
	unsigned int		(*snd_pcm_info_get_subdevice)(const snd_pcm_info_t *obj);
111
	snd_pcm_stream_t  	(*snd_pcm_info_get_stream)(const snd_pcm_info_t *obj);
112
	int			(*snd_pcm_info_get_card)(const snd_pcm_info_t *obj);
113
	const char *		(*snd_pcm_info_get_id)(const snd_pcm_info_t *obj);
114
	const char *		(*snd_pcm_info_get_name)(const snd_pcm_info_t *obj);
115
	const char *		(*snd_pcm_info_get_subdevice_name)(const snd_pcm_info_t *obj);
116
	snd_pcm_class_t		(*snd_pcm_info_get_class)(const snd_pcm_info_t *obj);
117
	snd_pcm_subclass_t	(*snd_pcm_info_get_subclass)(const snd_pcm_info_t *obj);
118
	unsigned int		(*snd_pcm_info_get_subdevices_count)(const snd_pcm_info_t *obj);
119
	unsigned int		(*snd_pcm_info_get_subdevices_avail)(const snd_pcm_info_t *obj);
120
	snd_pcm_sync_id_t	(*snd_pcm_info_get_sync)(const snd_pcm_info_t *obj);
121
	void			(*snd_pcm_info_set_device)(snd_pcm_info_t *obj, unsigned int val);
122
	void			(*snd_pcm_info_set_subdevice)(snd_pcm_info_t *obj, unsigned int val);
123
	void			(*snd_pcm_info_set_stream)(snd_pcm_info_t *obj, snd_pcm_stream_t val);
124
125
	/*	descriptions		*/
126
	const char *		(*snd_pcm_type_name)(snd_pcm_type_t type);
127
	const char * 		(*snd_pcm_stream_name)(const snd_pcm_stream_t stream);
128
	const char * 		(*snd_pcm_access_name)(const snd_pcm_access_t _access);
129
	const char * 		(*snd_pcm_format_name)(const snd_pcm_format_t format);
130
	const char * 		(*snd_pcm_format_description)(const snd_pcm_format_t format);
131
	const char * 		(*snd_pcm_subformat_name)(const snd_pcm_subformat_t subformat);
132
	const char * 		(*snd_pcm_subformat_description)(const snd_pcm_subformat_t subformat);
133
	snd_pcm_format_t	(*snd_pcm_format_value)(const char *name);
134
	const char * 		(*snd_pcm_tstamp_mode_name)(const snd_pcm_tstamp_t mode);
135
	const char * 		(*snd_pcm_state_name)(const snd_pcm_state_t state);
136
137
	/*	debug			*/
138
	int 			(*snd_pcm_dump)(snd_pcm_t *pcm, snd_output_t *out);
139
	int 			(*snd_pcm_dump_hw_setup)(snd_pcm_t *pcm, snd_output_t *out);
140
	int 			(*snd_pcm_dump_sw_setup)(snd_pcm_t *pcm, snd_output_t *out);
141
	int 			(*snd_pcm_dump_setup)(snd_pcm_t *pcm, snd_output_t *out);
142
	int 			(*snd_pcm_hw_params_dump)(snd_pcm_hw_params_t *params, snd_output_t *out);
143
	int 			(*snd_pcm_sw_params_dump)(snd_pcm_sw_params_t *params, snd_output_t *out);
144
	int 			(*snd_pcm_status_dump)(snd_pcm_status_t *status, snd_output_t *out);
145
146
	/*	hardware		*/
147
	int			(*snd_pcm_hw_params_any)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
148
	int			(*snd_pcm_hw_params_get_sbits)(const snd_pcm_hw_params_t *params);
149
	size_t			(*snd_pcm_hw_params_sizeof)(void);
150
	int			(*snd_pcm_hw_params_malloc)(snd_pcm_hw_params_t **ptr);
151
	void			(*snd_pcm_hw_params_free)(snd_pcm_hw_params_t *obj);
152
	void			(*snd_pcm_hw_params_copy)(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src);
153
	int			(*snd_pcm_hw_params_set_access)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access);
154
	int			(*snd_pcm_hw_params_get_access)(const snd_pcm_hw_params_t *params, snd_pcm_access_t *_access);
155
	int			(*snd_pcm_hw_params_set_access_mask)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
156
	int			(*snd_pcm_hw_params_get_access_mask)(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask);
157
	void			(*snd_pcm_access_mask_none)(snd_pcm_access_mask_t *mask);
158
	void			(*snd_pcm_access_mask_any)(snd_pcm_access_mask_t *mask);
159
	int			(*snd_pcm_access_mask_empty)(const snd_pcm_access_mask_t *mask);
160
	void			(*snd_pcm_access_mask_set)(snd_pcm_access_mask_t *mask, snd_pcm_access_t val);
161
	void			(*snd_pcm_access_mask_reset)(snd_pcm_access_mask_t *mask, snd_pcm_access_t val);
162
	void			(*snd_pcm_format_mask_none)(snd_pcm_format_mask_t *mask);
163
	void			(*snd_pcm_format_mask_any)(snd_pcm_format_mask_t *mask);
164
	int			(*snd_pcm_format_mask_empty)(const snd_pcm_format_mask_t *mask);
165
	void			(*snd_pcm_format_mask_set)(snd_pcm_format_mask_t *mask, snd_pcm_format_t val);
166
	void			(*snd_pcm_format_mask_reset)(snd_pcm_format_mask_t *mask, snd_pcm_format_t val);
167
	int			(*snd_pcm_format_mask_malloc)(snd_pcm_format_mask_t **ptr);
168
	void			(*snd_pcm_format_mask_free)(snd_pcm_format_mask_t *obj);
169
	void			(*snd_pcm_format_mask_copy)(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src);
170
	int			(*snd_pcm_hw_params_get_format)(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val);
171
	int			(*snd_pcm_hw_params_set_format)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val);
172
	int			(*snd_pcm_hw_params_set_format_mask)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
173
	void			(*snd_pcm_hw_params_get_format_mask)(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask);
174
	int			(*snd_pcm_hw_params_get_subformat)(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat);
175
	int			(*snd_pcm_hw_params_set_subformat)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat);
176
	int			(*snd_pcm_hw_params_set_subformat_mask)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
177
	void			(*snd_pcm_hw_params_get_subformat_mask)(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask);
178
	int			(*snd_pcm_hw_params_get_rate)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
179
	int			(*snd_pcm_hw_params_get_rate_min)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
180
	int			(*snd_pcm_hw_params_get_rate_max)(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
181
	int			(*snd_pcm_hw_params_set_rate)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir);
182
	int			(*snd_pcm_hw_params_set_rate_min)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
183
	int			(*snd_pcm_hw_params_set_rate_max)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
184
	int			(*snd_pcm_hw_params_set_rate_minmax)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
185
	int			(*snd_pcm_hw_params_set_rate_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
186
	int			(*snd_pcm_hw_params_set_rate_resample)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
187
	int			(*snd_pcm_hw_params_get_rate_resample)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
188
	int			(*snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *params, unsigned int *val);
189
	int			(*snd_pcm_hw_params_set_channels)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
190
	int			(*snd_pcm_hw_params_get_min_align)(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val);
191
192
	/*	external PCM plugins		*/
193
	int			(*snd_pcm_parse_control_id)(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp, int *cchannelsp, int *hwctlp);
194
195
	/*	configuration			*/
196
	int			(*snd_config_make_compound)(snd_config_t **, const char *, int);
197
	int			(*snd_config_make)(snd_config_t **, const char *, snd_config_type_t);
198
	int			(*snd_config_make_string)(snd_config_t **config, const char *key);
199
	int			(*snd_config_make_integer)(snd_config_t **config, const char *key);
200
	int			(*snd_config_make_integer64)(snd_config_t **config, const char *key);
201
	int			(*snd_config_make_real)(snd_config_t **config, const char *key);
202
	int			(*snd_config_make_pointer)(snd_config_t **config, const char *key);
203
	int			(*snd_config_imake_string)(snd_config_t **config, const char *key, const char *ascii);
204
	int			(*snd_config_imake_integer)(snd_config_t **config, const char *key, const long value);
205
	int			(*snd_config_imake_integer64)(snd_config_t **config, const char *key, const long long value);
206
	int			(*snd_config_imake_real)(snd_config_t **config, const char *key, const double value);
207
	int			(*snd_config_imake_pointer)(snd_config_t **config, const char *key, const void *ptr);
208
	int			(*snd_config_load)(snd_config_t *, snd_input_t *);
209
	int			(*snd_config_top)(snd_config_t **);
210
	int			(*snd_config_load_override)(snd_config_t *config, snd_input_t *in);
211
	int			(*snd_config_save)(snd_config_t *config, snd_output_t *out);
212
	int			(*snd_config_update)(void);
213
	int			(*snd_config_search)(snd_config_t *config, const char *key, snd_config_t **result);
214
	int			(*snd_config_searchv)(snd_config_t *config, snd_config_t **result,...);
215
	int			(*snd_config_search_definition)(snd_config_t *config, const char *base, const char *key, snd_config_t **result);
216
	int			(*snd_config_expand)(snd_config_t *config, snd_config_t *root, const char *args, snd_config_t *private_data, snd_config_t **result);
217
	int			(*snd_config_evaluate)(snd_config_t *config, snd_config_t *root, snd_config_t *private_data, snd_config_t **result);
218
	int			(*snd_config_add)(snd_config_t *config, snd_config_t *leaf);
219
	int			(*snd_config_delete)(snd_config_t *config);
220
	int			(*snd_config_delete_compound_members)(const snd_config_t *config);
221
	int			(*snd_config_copy)(snd_config_t **dst, snd_config_t *src);
222
	snd_config_type_t	(*snd_config_get_type)(const snd_config_t *config);
223
	int			(*snd_config_set_id)(snd_config_t *config, const char *id);
224
	int			(*snd_config_set_integer)(snd_config_t *config, long value);
225
	int			(*snd_config_set_integer64)(snd_config_t *config, long long value);
226
	int			(*snd_config_set_real)(snd_config_t *config, double value);
227
	int			(*snd_config_set_string)(snd_config_t *config, const char *value);
228
	int			(*snd_config_set_ascii)(snd_config_t *config, const char *ascii);
229
	int			(*snd_config_set_pointer)(snd_config_t *config, const void *ptr);
230
	int			(*snd_config_get_id)(const snd_config_t *config, const char **value);
231
	int			(*snd_config_get_integer)(const snd_config_t *config, long *value);
232
	int			(*snd_config_get_integer64)(const snd_config_t *config, long long *value);
233
	int			(*snd_config_get_real)(const snd_config_t *config, double *value);
234
	int			(*snd_config_get_ireal)(const snd_config_t *config, double *value);
235
	int			(*snd_config_get_string)(const snd_config_t *config, const char **value);
236
	int			(*snd_config_get_ascii)(const snd_config_t *config, char **value);
237
	int			(*snd_config_get_pointer)(const snd_config_t *config, const void **value);
238
	snd_config_iterator_t	(*snd_config_iterator_first)(const snd_config_t *node);
239
	snd_config_iterator_t	(*snd_config_iterator_next)(const snd_config_iterator_t iterator);
240
	snd_config_iterator_t	(*snd_config_iterator_end)(const snd_config_t *node);
241
	snd_config_t *		(*snd_config_iterator_entry)(const snd_config_iterator_t iterator);
242
	int			(*snd_config_test_id)(const snd_config_t *config, const char *id);
243
	int			(*snd_names_list)(const char *iface, snd_devname_t **list);
244
	int			(*snd_config_get_bool_ascii)(const char *ascii);
245
	int			(*snd_config_get_bool)(const snd_config_t *conf);
246
	int			(*snd_config_get_ctl_iface_ascii)(const char *ascii);
247
	int			(*snd_config_get_ctl_iface)(const snd_config_t *conf);
248
249
	/*	custom methods			*/
250
	int			(*setup_fifo)(struct _alsa *, const char *);
251
252
} alsa;
253
254
alsa * g_alsa;
255
256
int APP_CC
257
g_alsa_init(void);
258
259
int APP_CC
260
g_alsa_deinit(void);
261
262
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/asound.conf (+40 lines)
Line 0    Link Here 
1
pcm.xrdp {
2
    @args [ FILE RATE ]
3
    @args.FILE {
4
      type string;
5
      default {
6
	@func getenv
7
	vars [ AUDIO_FIFO_PATH ]
8
	default "/dev/null"
9
      }
10
    }
11
    @args.RATE {
12
      type integer;
13
      default {
14
	@func igetenv
15
	vars [ AUDIO_RATE ]
16
	default 44100
17
      }
18
    }
19
    type plug;
20
    slave.pcm {
21
      type rate;
22
      slave {
23
        pcm {
24
          type file;
25
          slave { pcm { type null; } }
26
          file $FILE;
27
        }
28
        rate $RATE
29
      }
30
      converter "samplerate"
31
    }
32
}
33
34
pcm.dmixer { type dmix; slave.pcm xrdp; }
35
pcm.dsp0 { type plug; slave.pcm dmixer; }
36
ctl.mixer0 { type dmix; slave.pcm xrdp; }
37
pcm.main { type plug; slave.pcm xrdp; }
38
ctl.main { type plug; slave.pcm mixer0; }
39
pcm.!default { type plug; slave.pcm main; }
40
ctl.!default { type plug; slave.pcm main; }
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/chansrv.c (-181 / +791 lines)
 Lines 17-22    Link Here 
17
   Copyright (C) Jay Sorg 2009
17
   Copyright (C) Jay Sorg 2009
18
*/
18
*/
19
19
20
#include <stddef.h>
21
#include <string.h>
22
#include <pthread.h>
23
#include <glob.h>
24
#include <pwd.h>
25
#include <unistd.h>
26
#include <sys/types.h>
27
#include <sys/stat.h>
28
20
#include "arch.h"
29
#include "arch.h"
21
#include "os_calls.h"
30
#include "os_calls.h"
22
#include "thread_calls.h"
31
#include "thread_calls.h"
 Lines 26-68    Link Here 
26
#include "sound.h"
35
#include "sound.h"
27
#include "clipboard.h"
36
#include "clipboard.h"
28
#include "devredir.h"
37
#include "devredir.h"
38
#include "drdynvc.h"
29
#include "list.h"
39
#include "list.h"
30
#include "file.h"
40
#include "file.h"
31
#include "file_loc.h"
41
#include "file_loc.h"
42
#include "thread_calls.h"
43
#include "thread_macros.h"
44
#include "dbg.h"
32
45
33
static struct trans* g_lis_trans = 0;
46
tc_t		g_out_mutex;// = TC_MUTEX_INITIALIZER;
34
static struct trans* g_con_trans = 0;
47
tc_p		mutex_out = (tc_p)(&g_out_mutex);
35
static struct chan_item g_chan_items[32];
48
tc_t		g_chan_mutex;// = TC_MUTEX_INITIALIZER;
36
static int g_num_chan_items = 0;
49
tc_p		mutex_chan = (tc_p)NULL;
37
static int g_cliprdr_index = -1;
50
tc_t		g_event_mutex;// = TC_MUTEX_INITIALIZER;
38
static int g_rdpsnd_index = -1;
51
tc_p		mutex_event = (tc_p)(&g_event_mutex);
39
static int g_rdpdr_index = -1;
52
tc_t		g_mem_mutex;// = TC_MUTEX_INITIALIZER;
53
tc_p		mutex_mem = (tc_p)(&g_mem_mutex);
54
55
tc_t		g_mutattr;
56
tc_p		g_attr = (tc_p)(&g_mutattr);
57
58
static struct trans * g_lis_trans = 0;
59
static struct trans * g_con_trans = 0;
60
static struct chan_item g_chan_items[64];
61
static ptrdiff_t g_num_chan_items = 0;
62
static ptrdiff_t g_cliprdr_index = -1;
63
static ptrdiff_t g_rdpsnd_index = -1;
64
static ptrdiff_t g_rdpdr_index = -1;
65
static ptrdiff_t g_drdynvc_index = -1;
40
66
41
static tbus g_term_event = 0;
67
static tbus g_term_event = 0;
42
static tbus g_thread_done_event = 0;
68
static tbus g_thread_done_event = 0;
43
69
44
static int g_use_unix_socket = 0;
70
static unsigned char g_use_unix_socket = 0;
71
static unsigned char g_atomic = 0;
72
static unsigned char verbose = 0;
45
73
46
int g_display_num = 0;
74
int g_display_num = 0;
47
int g_cliprdr_chan_id = -1; /* cliprdr */
75
int g_cliprdr_chan_id = -1; /* cliprdr */
48
int g_rdpsnd_chan_id = -1; /* rdpsnd */
76
int g_rdpsnd_chan_id = -1; /* rdpsnd */
77
int g_audio_input_chan_id = -1; /* audio_input */
49
int g_rdpdr_chan_id = -1; /* rdpdr */
78
int g_rdpdr_chan_id = -1; /* rdpdr */
79
int g_drdynvc_chan_id = -1; /* dynamic virtual channels */
50
80
51
/*****************************************************************************/
81
/*****************************************************************************/
52
/* returns error */
82
/* returns error */
53
int APP_CC
83
ptrdiff_t APP_CC
54
send_channel_data(int chan_id, char* data, int size)
84
send_channel_data(int chan_id, char * data, size_t size)
55
{
85
{
56
  struct stream* s;
86
  struct stream * s = (struct stream *)NULL;
57
  int chan_flags;
87
  int chan_flags = 0;
58
  int total_size;
88
  ptrdiff_t total_size = 0;
59
  int sent;
89
  ptrdiff_t sent = 0;
60
  int rv;
90
  ptrdiff_t rv = 0;
91
  unsigned char tlocked = 0;
92
93
  TC_MUTEX_LOCK(mutex_chan);
94
95
  if (g_con_trans == NULL || g_con_trans->lock == NULL) {
96
    MDBGLOG("chansrv","ERROR\t[%s()]: g_con_trans is NULL",__func__);
97
    rv = 1;
98
    goto end;
99
  }
100
  else {
101
    TC_MUTEX_LOCK(g_con_trans->lock);
102
    tlocked = 1;
103
  }
61
104
62
  s = trans_get_out_s(g_con_trans, 8192);
105
  s = trans_get_out_s(g_con_trans, MAX_STREAM);
63
  if (s == 0)
106
  if (s == 0)
64
  {
107
  {
65
    return 1;
108
    MDBGLOG("chansrv","ERROR\t[%s()]: s is NULL",__func__);
109
    rv = 1;
110
    goto end;
66
  }
111
  }
67
  rv = 0;
112
  rv = 0;
68
  sent = 0;
113
  sent = 0;
 Lines 95-124    Link Here 
95
      break;
140
      break;
96
    }
141
    }
97
    sent += size;
142
    sent += size;
98
    s = trans_get_out_s(g_con_trans, 8192);
143
    s = trans_get_out_s(g_con_trans, MAX_STREAM);
144
  }
145
146
 end:;
147
  if (tlocked) {
148
    TC_MUTEX_UNLOCK(g_con_trans->lock);
149
    tlocked = 0;
99
  }
150
  }
151
  TC_MUTEX_UNLOCK(mutex_chan);
100
  return rv;
152
  return rv;
101
}
153
}
102
154
103
/*****************************************************************************/
155
/*****************************************************************************/
104
/* returns error */
156
/* returns error */
105
static int APP_CC
157
ptrdiff_t APP_CC
106
send_init_response_message(void)
158
send_channel_data_multiple_atomic(int chan_id, unsigned int num, char * datas[], size_t sizes[])
107
{
159
{
108
  struct stream* s;
160
  struct stream * s = (struct stream *)NULL;
161
  int chan_flags = 0;
162
  ptrdiff_t rv = 0;
163
  ptrdiff_t idx = 0;
164
  unsigned char tlocked = 0;
165
166
  TC_MUTEX_LOCK(mutex_chan);
167
168
  if (g_con_trans == NULL || g_con_trans->lock == NULL) {
169
    rv = 1;
170
    goto end;
171
  }
172
  else {
173
    TC_MUTEX_LOCK(g_con_trans->lock);
174
    tlocked = 1;
175
  }
109
176
110
  LOG(1, ("send_init_response_message:"));
177
  s = trans_get_out_s(g_con_trans, MAX_STREAM);
111
  s = trans_get_out_s(g_con_trans, 8192);
112
  if (s == 0)
178
  if (s == 0)
113
  {
179
  {
114
    return 1;
180
    rv = 1;
181
    goto end;
182
  }
183
  rv = 0;
184
185
  for (idx = 0; idx < num; idx++) {
186
187
    ptrdiff_t total_size = 0;
188
    ptrdiff_t sent = 0;
189
    ptrdiff_t size = 0;
190
    char * data = (char *)NULL;
191
192
    size = sizes[idx];
193
    data = datas[idx];
194
195
    total_size = size;
196
    while (sent < total_size) {
197
      size = MIN(1600, (total_size - sent));
198
      chan_flags = 0;
199
      if (sent == 0) {
200
        chan_flags |= 1; /* first */
201
      }
202
      if (size + sent == total_size) {
203
        chan_flags |= 2; /* last */
204
      }
205
      out_uint32_le(s, 0); /* version */
206
      out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
207
      out_uint32_le(s, 8); /* msg id */
208
      out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
209
      out_uint16_le(s, chan_id);
210
      out_uint16_le(s, chan_flags);
211
      out_uint16_le(s, size);
212
      out_uint32_le(s, total_size);
213
      out_uint8a(s, data + sent, size);
214
      s_mark_end(s);
215
      rv = trans_force_write(g_con_trans);
216
      if (rv != 0) {
217
        break;
218
      }
219
      sent += size;
220
      s = trans_get_out_s(g_con_trans, MAX_STREAM);
221
    }
222
223
  }
224
225
 end:;
226
  if (tlocked) {
227
    TC_MUTEX_UNLOCK(g_con_trans->lock);
228
    tlocked = 0;
115
  }
229
  }
116
  out_uint32_le(s, 0); /* version */
230
  TC_MUTEX_UNLOCK(mutex_chan);
117
  out_uint32_le(s, 8 + 8); /* size */
231
  return rv;
118
  out_uint32_le(s, 2); /* msg id */
232
}
119
  out_uint32_le(s, 8); /* size */
233
120
  s_mark_end(s);
234
/*****************************************************************************/
121
  return trans_force_write(g_con_trans);
235
/* returns error */
236
static int APP_CC
237
send_init_response_message(void)
238
{
239
  int rv = 0;
240
  unsigned char tlocked = 0;
241
  struct stream * s = (struct stream *)NULL;
242
  TC_MUTEX_LOCK(mutex_chan);
243
  if (g_con_trans == NULL || g_con_trans->lock == NULL) {
244
    rv = 1;
245
    goto end;
246
  }
247
  else {
248
    TC_MUTEX_LOCK(g_con_trans->lock);
249
    tlocked = 1;
250
  }
251
  s = trans_get_out_s(g_con_trans, MAX_STREAM);
252
  if (s == NULL) {
253
    rv = 1;
254
  }
255
  else {
256
    out_uint32_le(s, 0); /* version */
257
    out_uint32_le(s, 8 + 8); /* size */
258
    out_uint32_le(s, 2); /* msg id */
259
    out_uint32_le(s, 8); /* size */
260
    s_mark_end(s);
261
    rv = trans_force_write(g_con_trans);
262
  }
263
 end:;
264
  if (tlocked) {
265
    TC_MUTEX_UNLOCK(g_con_trans->lock);
266
    tlocked = 0;
267
  }
268
  TC_MUTEX_UNLOCK(mutex_chan);
269
  return rv;
122
}
270
}
123
271
124
/*****************************************************************************/
272
/*****************************************************************************/
 Lines 126-145    Link Here 
126
static int APP_CC
274
static int APP_CC
127
send_channel_setup_response_message(void)
275
send_channel_setup_response_message(void)
128
{
276
{
129
  struct stream* s;
277
  int rv = 0;
278
  unsigned char tlocked = 0;
279
  struct stream * s = NULL;
130
280
131
  LOG(10, ("send_channel_setup_response_message:"));
281
  LOG(10, ("send_channel_setup_response_message:"));
132
  s = trans_get_out_s(g_con_trans, 8192);
282
  MDBGLOG("chansrv","INFO\t[%s()]: called",__func__);
283
284
  TC_MUTEX_LOCK(mutex_chan);
285
286
  if (g_con_trans == NULL || g_con_trans->lock == NULL) {
287
    rv = 1;
288
    goto end;
289
  }
290
  else {
291
    TC_MUTEX_LOCK(g_con_trans->lock);
292
    tlocked = 1;
293
  }
294
295
  s = trans_get_out_s(g_con_trans, MAX_STREAM);
133
  if (s == 0)
296
  if (s == 0)
134
  {
297
  {
135
    return 1;
298
    rv = 1;
299
  }
300
  else {
301
    out_uint32_le(s, 0); /* version */
302
    out_uint32_le(s, 8 + 8); /* size */
303
    out_uint32_le(s, 4); /* msg id */
304
    out_uint32_le(s, 8); /* size */
305
    s_mark_end(s);
306
    rv = trans_force_write(g_con_trans);
136
  }
307
  }
137
  out_uint32_le(s, 0); /* version */
308
138
  out_uint32_le(s, 8 + 8); /* size */
309
 end:;
139
  out_uint32_le(s, 4); /* msg id */
310
  if (tlocked) {
140
  out_uint32_le(s, 8); /* size */
311
    TC_MUTEX_UNLOCK(g_con_trans->lock);
141
  s_mark_end(s);
312
    tlocked = 0;
142
  return trans_force_write(g_con_trans);
313
  }
314
  TC_MUTEX_UNLOCK(mutex_chan);  
315
  return rv;
143
}
316
}
144
317
145
/*****************************************************************************/
318
/*****************************************************************************/
 Lines 147-166    Link Here 
147
static int APP_CC
320
static int APP_CC
148
send_channel_data_response_message(void)
321
send_channel_data_response_message(void)
149
{
322
{
150
  struct stream* s;
323
  int rv = 0;
324
  unsigned char tlocked = 0;
325
  struct stream * s = NULL;
151
326
152
  LOG(10, ("send_channel_data_response_message:"));
327
  if (verbose) {
153
  s = trans_get_out_s(g_con_trans, 8192);
328
    MDBGLOG("chansrv","INFO\t[%s()]: called",__func__);
154
  if (s == 0)
329
    //LOG(10, ("send_channel_data_response_message:"));
330
  }
331
332
  TC_MUTEX_LOCK(mutex_chan);
333
334
  if (g_con_trans == NULL || g_con_trans->lock == NULL) {
335
    rv = 1;
336
    goto end;
337
  }
338
  else {
339
    TC_MUTEX_LOCK(g_con_trans->lock);
340
    tlocked = 1;
341
  }
342
343
  s = trans_get_out_s(g_con_trans, MAX_STREAM);
344
  if (s == NULL)
155
  {
345
  {
156
    return 1;
346
    rv = 1;
347
  }
348
  else {
349
    out_uint32_le(s, 0); /* version */
350
    out_uint32_le(s, 8 + 8); /* size */
351
    out_uint32_le(s, 6); /* msg id */
352
    out_uint32_le(s, 8); /* size */
353
    s_mark_end(s);
354
    rv = trans_force_write(g_con_trans);
355
  }
356
357
 end:;
358
  if (tlocked) {
359
    TC_MUTEX_UNLOCK(g_con_trans->lock);
157
  }
360
  }
158
  out_uint32_le(s, 0); /* version */
361
  TC_MUTEX_UNLOCK(mutex_chan);
159
  out_uint32_le(s, 8 + 8); /* size */
362
  return rv;
160
  out_uint32_le(s, 6); /* msg id */
161
  out_uint32_le(s, 8); /* size */
162
  s_mark_end(s);
163
  return trans_force_write(g_con_trans);
164
}
363
}
165
364
166
/*****************************************************************************/
365
/*****************************************************************************/
 Lines 168-175    Link Here 
168
static int APP_CC
367
static int APP_CC
169
process_message_init(struct stream* s)
368
process_message_init(struct stream* s)
170
{
369
{
370
  unsigned char tunlocked = 0;
171
  LOG(10, ("process_message_init:"));
371
  LOG(10, ("process_message_init:"));
372
  MDBGLOG("chansrv","INFO\t[%s()]: called",__func__);
373
  if (g_con_trans != NULL && g_con_trans->lock != NULL) {
374
    TC_MUTEX_UNLOCK(g_con_trans->lock);
375
    tunlocked = 1;
376
  }
377
  TC_MUTEX_UNLOCK(mutex_chan);
172
  return send_init_response_message();
378
  return send_init_response_message();
379
  TC_MUTEX_LOCK(mutex_chan);
380
  if (tunlocked) {
381
    TC_MUTEX_LOCK(g_con_trans->lock);
382
  }
173
}
383
}
174
384
175
/*****************************************************************************/
385
/*****************************************************************************/
 Lines 177-186    Link Here 
177
static int APP_CC
387
static int APP_CC
178
process_message_channel_setup(struct stream* s)
388
process_message_channel_setup(struct stream* s)
179
{
389
{
180
  int num_chans;
390
  int num_chans = 0;
181
  int index;
391
  ptrdiff_t index = 0;
182
  int rv;
392
  int rv = 0;
183
  struct chan_item* ci;
393
  unsigned char tunlocked = 0;
394
  struct chan_item * ci = (struct chan_item *)NULL;
395
396
  //TC_MUTEX_LOCK(mutex_chan);
184
397
185
  g_num_chan_items = 0;
398
  g_num_chan_items = 0;
186
  g_cliprdr_index = -1;
399
  g_cliprdr_index = -1;
 Lines 188-197    Link Here 
188
  g_rdpdr_index = -1;
401
  g_rdpdr_index = -1;
189
  g_cliprdr_chan_id = -1;
402
  g_cliprdr_chan_id = -1;
190
  g_rdpsnd_chan_id = -1;
403
  g_rdpsnd_chan_id = -1;
404
  g_audio_input_chan_id = -1;
191
  g_rdpdr_chan_id = -1;
405
  g_rdpdr_chan_id = -1;
192
  LOG(10, ("process_message_channel_setup:"));
406
  g_drdynvc_chan_id = -1;
407
193
  in_uint16_le(s, num_chans);
408
  in_uint16_le(s, num_chans);
194
  LOG(10, ("process_message_channel_setup: num_chans %d", num_chans));
409
  LOG(10, ("process_message_channel_setup: num_chans %d", num_chans));
410
  MDBGLOG("chansrv", "INFO\t[%s()]: num_chans = %d", __func__, num_chans);
411
195
  for (index = 0; index < num_chans; index++)
412
  for (index = 0; index < num_chans; index++)
196
  {
413
  {
197
    ci = &(g_chan_items[g_num_chan_items]);
414
    ci = &(g_chan_items[g_num_chan_items]);
 Lines 199-206    Link Here 
199
    in_uint8a(s, ci->name, 8);
416
    in_uint8a(s, ci->name, 8);
200
    in_uint16_le(s, ci->id);
417
    in_uint16_le(s, ci->id);
201
    in_uint16_le(s, ci->flags);
418
    in_uint16_le(s, ci->flags);
202
    LOG(10, ("process_message_channel_setup: chan name '%s' "
419
    //LOG(10, ("process_message_channel_setup: channel name = '%s'; id = %d; flags = %8.8x", ci->name, ci->id, ci->flags));
203
             "id %d flags %8.8x", ci->name, ci->id, ci->flags));
420
    MDBGLOG("chansrv", "INFO\t[%s()]: channel name = \"%s\"; id = %d; flags = 0x%8.8x", __func__, ci->name, ci->id, ci->flags);
204
    if (g_strcasecmp(ci->name, "cliprdr") == 0)
421
    if (g_strcasecmp(ci->name, "cliprdr") == 0)
205
    {
422
    {
206
      g_cliprdr_index = g_num_chan_items;
423
      g_cliprdr_index = g_num_chan_items;
 Lines 216-224    Link Here 
216
      g_rdpdr_index = g_num_chan_items;
433
      g_rdpdr_index = g_num_chan_items;
217
      g_rdpdr_chan_id = ci->id;
434
      g_rdpdr_chan_id = ci->id;
218
    }
435
    }
436
    else if (g_strcasecmp(ci->name, "drdynvc") == 0)
437
    {
438
      g_drdynvc_index = g_num_chan_items;
439
      g_drdynvc_chan_id = ci->id;
440
    }
219
    g_num_chan_items++;
441
    g_num_chan_items++;
220
  }
442
  }
443
  if (g_con_trans != NULL && g_con_trans->lock != NULL) {
444
    TC_MUTEX_UNLOCK(g_con_trans->lock);
445
    tunlocked = 1;
446
  }
447
  TC_MUTEX_UNLOCK(mutex_chan);
221
  rv = send_channel_setup_response_message();
448
  rv = send_channel_setup_response_message();
449
  TC_MUTEX_LOCK(mutex_chan);
450
  if (tunlocked) {
451
    TC_MUTEX_LOCK(g_con_trans->lock);
452
  }
222
  if (g_cliprdr_index >= 0)
453
  if (g_cliprdr_index >= 0)
223
  {
454
  {
224
    clipboard_init();
455
    clipboard_init();
 Lines 229-257    Link Here 
229
  }
460
  }
230
  if (g_rdpdr_index >= 0)
461
  if (g_rdpdr_index >= 0)
231
  {
462
  {
232
    dev_redir_init();
463
    rdpdr_init();
464
  }
465
  if (g_drdynvc_index >= 0)
466
  {
467
    drdynvc_init();
233
  }
468
  }
234
  return rv;
469
  return rv;
235
}
470
}
236
471
237
/*****************************************************************************/
472
/*****************************************************************************
238
/* returns error */
473
 *
474
 * - returns error
475
 * - caller must hold the "g_con_trans->lock" mutex
476
 *
477
 *****************************************************************************/
239
static int APP_CC
478
static int APP_CC
240
process_message_channel_data(struct stream* s)
479
process_message_channel_data(struct stream* s)
241
{
480
{
242
  int chan_id;
481
  int rv = 0;
243
  int chan_flags;
482
  int chan_id = 0;
244
  int rv;
483
  int chan_flags = 0;
245
  int length;
484
  ptrdiff_t length = 0;
246
  int total_length;
485
  ptrdiff_t total_length = 0;
486
  unsigned char tunlocked = 0;
487
488
  if (verbose) {
489
    MDBGLOG("chansrv","INFO\t[%s()]: called (s = %p)",__func__,s);
490
  }
247
491
248
  in_uint16_le(s, chan_id);
492
  in_uint16_le(s, chan_id);
249
  in_uint16_le(s, chan_flags);
493
  in_uint16_le(s, chan_flags);
250
  in_uint16_le(s, length);
494
  in_uint16_le(s, length);
251
  in_uint32_le(s, total_length);
495
  in_uint32_le(s, total_length);
252
  LOG(10, ("process_message_channel_data: chan_id %d "
496
  LOG(10, ("process_message_channel_data: chan_id = %d; chan_flags = %d", chan_id, chan_flags));
253
           "chan_flags %d", chan_id, chan_flags));
497
  if (g_con_trans != NULL && g_con_trans->lock != NULL) {
498
    TC_MUTEX_UNLOCK(g_con_trans->lock);
499
    tunlocked = 1;
500
  }
501
  TC_MUTEX_UNLOCK(mutex_chan);
254
  rv = send_channel_data_response_message();
502
  rv = send_channel_data_response_message();
503
  TC_MUTEX_LOCK(mutex_chan);
504
  if (tunlocked) {
505
    TC_MUTEX_LOCK(g_con_trans->lock);
506
  }
255
  if (rv == 0)
507
  if (rv == 0)
256
  {
508
  {
257
    if (chan_id == g_cliprdr_chan_id)
509
    if (chan_id == g_cliprdr_chan_id)
 Lines 264-270    Link Here 
264
    }
516
    }
265
    else if (chan_id == g_rdpdr_chan_id)
517
    else if (chan_id == g_rdpdr_chan_id)
266
    {
518
    {
267
      rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length);
519
      rv = rdpdr_data_in(s, chan_id, chan_flags, length, total_length);
520
    }
521
    else if (chan_id == g_drdynvc_chan_id)
522
    {
523
      rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length);
268
    }
524
    }
269
  }
525
  }
270
  return rv;
526
  return rv;
 Lines 272-281    Link Here 
272
528
273
/*****************************************************************************/
529
/*****************************************************************************/
274
/* returns error */
530
/* returns error */
275
static int APP_CC
531
static inline int APP_CC
276
process_message_channel_data_response(struct stream* s)
532
process_message_channel_data_response(struct stream* s)
277
{
533
{
278
  LOG(10, ("process_message_channel_data_response:"));
534
  if (verbose) {
535
    LOG(10, ("process_message_channel_data_response:"));
536
    MDBGLOG("chansrv","INFO\t[%s()]: called",__func__);
537
  }
279
  return 0;
538
  return 0;
280
}
539
}
281
540
 Lines 284-304    Link Here 
284
static int APP_CC
543
static int APP_CC
285
process_message(void)
544
process_message(void)
286
{
545
{
287
  struct stream* s;
546
  struct stream* s = (struct stream *)NULL;
288
  int size;
547
  int size = 0;
289
  int id;
548
  int id = 0;
290
  int rv;
549
  int rv = 0;
291
  char* next_msg;
550
  unsigned char tlocked = 0;
551
  char* next_msg = (char *)NULL;
292
552
553
  if (verbose) {
554
    MDBGLOG("chansrv","INFO\t[%s()]: called",__func__);
555
  }
556
557
  TC_MUTEX_LOCK(mutex_chan);
558
559
  TC_MUTEX_LOCK(mutex_event);
293
  if (g_con_trans == 0)
560
  if (g_con_trans == 0)
294
  {
561
  {
562
    TC_MUTEX_UNLOCK(mutex_event);
295
    return 1;
563
    return 1;
296
  }
564
  }
297
  s = trans_get_in_s(g_con_trans);
565
  else {
566
    if (g_con_trans->lock != NULL) {
567
      TC_MUTEX_LOCK(g_con_trans->lock);
568
      tlocked = 1;
569
    }
570
    s = trans_get_in_s(g_con_trans);
571
  }
298
  if (s == 0)
572
  if (s == 0)
299
  {
573
  {
574
    if (tlocked) {
575
      TC_MUTEX_UNLOCK(g_con_trans->lock);
576
      tlocked = 0;
577
    }
578
    TC_MUTEX_UNLOCK(mutex_event);
300
    return 1;
579
    return 1;
301
  }
580
  }
581
  else {
582
    TC_MUTEX_UNLOCK(mutex_event);
583
  }
302
  rv = 0;
584
  rv = 0;
303
  while (s_check_rem(s, 8))
585
  while (s_check_rem(s, 8))
304
  {
586
  {
 Lines 321-367    Link Here 
321
        rv = process_message_channel_data_response(s);
603
        rv = process_message_channel_data_response(s);
322
        break;
604
        break;
323
      default:
605
      default:
324
        LOG(0, ("process_message: error in process_message "
606
	LOG(0, ("[xdrp-chansrv]->process_message(): !!! ERROR (unknown msg = %d) !!!", id));
325
                "unknown msg %d", id));
607
	MDBGLOG("chansrv", "WARNING\t[%s()]: unknown msg = %d", __func__, id);
326
        break;
608
	break;
327
    }
609
    }
328
    if (rv != 0)
610
    if (rv != 0) {
329
    {
330
      break;
611
      break;
331
    }
612
    }
332
    s->p = next_msg;
613
    else {
614
      s->p = next_msg;
615
    }
616
  }
617
 end:;
618
  if (tlocked) {
619
    TC_MUTEX_UNLOCK(g_con_trans->lock);
620
    tlocked = 0;
333
  }
621
  }
622
  TC_MUTEX_UNLOCK(mutex_chan);
334
  return rv;
623
  return rv;
335
}
624
}
336
625
337
/*****************************************************************************/
626
/*****************************************************************************/
338
/* returns error */
627
/* returns error */
339
int DEFAULT_CC
628
size_t DEFAULT_CC
340
my_trans_data_in(struct trans* trans)
629
my_trans_data_in(struct trans* trans)
341
{
630
{
342
  struct stream* s;
631
  struct stream * s = (struct stream *)NULL;
343
  int id;
632
  int id = 0;
344
  int size;
633
  ptrdiff_t size = 0;
345
  int error;
634
  size_t error = 0;
346
635
347
  if (trans == 0)
636
  if (trans == 0)
348
  {
637
  {
349
    return 0;
638
    return 0;
350
  }
639
  }
640
  TC_MUTEX_LOCK(mutex_event);
351
  if (trans != g_con_trans)
641
  if (trans != g_con_trans)
352
  {
642
  {
643
    TC_MUTEX_UNLOCK(mutex_event);
353
    return 1;
644
    return 1;
354
  }
645
  }
355
  LOG(10, ("my_trans_data_in:"));
646
  else {
647
    TC_MUTEX_UNLOCK(mutex_event);
648
  }
649
  if (verbose) {
650
    MDBGLOG("chansrv", "INFO\t[%s()]: called (trans->sck = %d; trans->lock = %p)", __func__, trans->sck, trans->lock);
651
  }
652
  if (trans != NULL && trans->lock == NULL) {
653
    tc_t mattr;
654
    tc_p pattr = &mattr;
655
    g_memset(pattr,0,sizeof(tc_t));
656
    TC_MUTATTR_INIT(pattr);
657
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
658
    TC_MUTATTR_SETPSHARED(pattr,TC_PROCESS_SHARED);
659
    trans->lock = (tc_p)g_malloc(sizeof(tc_t), 1);
660
    TC_MUTEX_INIT(trans->lock, pattr);
661
  }
662
  TC_MUTEX_LOCK(trans->lock);
356
  s = trans_get_in_s(trans);
663
  s = trans_get_in_s(trans);
357
  in_uint32_le(s, id);
664
  in_uint32_le(s, id);
358
  in_uint32_le(s, size);
665
  in_uint32_le(s, size);
666
  if (verbose) {
667
    MDBGLOG("chansrv", "INFO\t[%s()]: id = %d", __func__, id);
668
  }
359
  error = trans_force_read(trans, size - 8);
669
  error = trans_force_read(trans, size - 8);
360
  if (error == 0)
670
  if (error == 0)
361
  {
671
  {
362
    /* here, the entire message block is read in, process it */
672
    /* here, the entire message block is read in, process it */
363
    error = process_message();
673
    error = process_message();
364
  }
674
  }
675
  TC_MUTEX_UNLOCK(trans->lock);
676
  if (verbose) {
677
    MDBGLOG("chansrv", "INFO\t[%s()]: done.", __func__);
678
  }
365
  return error;
679
  return error;
366
}
680
}
367
681
 Lines 373-397    Link Here 
373
  {
687
  {
374
    return 1;
688
    return 1;
375
  }
689
  }
690
  TC_MUTEX_LOCK(mutex_event);
376
  if (trans != g_lis_trans)
691
  if (trans != g_lis_trans)
377
  {
692
  {
693
    TC_MUTEX_UNLOCK(mutex_event);
378
    return 1;
694
    return 1;
379
  }
695
  }
380
  if (g_con_trans != 0) /* if already set, error */
696
  if (g_con_trans != 0) /* if already set, error */
381
  {
697
  {
698
    TC_MUTEX_UNLOCK(mutex_event);
382
    return 1;
699
    return 1;
383
  }
700
  }
384
  if (new_trans == 0)
701
  if (new_trans == 0)
385
  {
702
  {
703
    TC_MUTEX_UNLOCK(mutex_event);
386
    return 1;
704
    return 1;
387
  }
705
  }
388
  LOG(10, ("my_trans_conn_in:"));
706
  LOG(10, ("my_trans_conn_in:"));
707
  if (verbose) {
708
    MDBGLOG("chansrv", "INFO\t[%s()]: called", __func__);
709
  }
389
  g_con_trans = new_trans;
710
  g_con_trans = new_trans;
711
  if (g_con_trans != NULL && g_con_trans->lock == NULL) {
712
    tc_t mattr;
713
    tc_p pattr = &mattr;
714
    g_memset(pattr,0,sizeof(tc_t));
715
    TC_MUTATTR_INIT(pattr);
716
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
717
    TC_MUTATTR_SETPSHARED(pattr,TC_PROCESS_SHARED);
718
    g_con_trans->lock = (tc_p)g_malloc(sizeof(tc_t), 1);
719
    TC_MUTEX_INIT(g_con_trans->lock, pattr);
720
  }
721
  TC_MUTEX_LOCK(g_con_trans->lock);
390
  g_con_trans->trans_data_in = my_trans_data_in;
722
  g_con_trans->trans_data_in = my_trans_data_in;
391
  g_con_trans->header_size = 8;
723
  g_con_trans->header_size = 8;
724
  TC_MUTEX_UNLOCK(g_con_trans->lock);
392
  /* stop listening */
725
  /* stop listening */
393
  trans_delete(g_lis_trans);
726
  if (g_lis_trans == NULL || g_lis_trans->lock == NULL) {
394
  g_lis_trans = 0;
727
    trans_delete(g_lis_trans);
728
    g_lis_trans = 0;
729
  }
730
  else {
731
    tc_p tp = g_lis_trans->lock;
732
    TC_MUTEX_LOCK(tp);
733
    trans_delete(g_lis_trans);
734
    g_lis_trans = 0;
735
    TC_MUTEX_UNLOCK(tp);
736
    g_free(tp);
737
  }
738
  TC_MUTEX_UNLOCK(mutex_event);
739
  if (verbose) {
740
    MDBGLOG("chansrv", "INFO\t[%s()]: done.", __func__);
741
  }
395
  return 0;
742
  return 0;
396
}
743
}
397
744
 Lines 400-508    Link Here 
400
setup_listen(void)
747
setup_listen(void)
401
{
748
{
402
  char port[256];
749
  char port[256];
403
  int error;
750
  int error = 0;
751
  int res = 0;
752
753
  g_memset(port,0,sizeof(port));
404
754
755
  TC_MUTEX_LOCK(mutex_event);
405
  if (g_lis_trans != 0)
756
  if (g_lis_trans != 0)
406
  {
757
  {
758
    unsigned char tlock = 0;
759
    if (g_lis_trans->lock != NULL) {
760
      TC_MUTEX_LOCK(g_lis_trans->lock);
761
      tlock = 1;
762
    }
407
    trans_delete(g_lis_trans);
763
    trans_delete(g_lis_trans);
764
    if (tlock > 0) {
765
      TC_MUTEX_UNLOCK(g_lis_trans->lock);
766
    }
408
  }
767
  }
409
  if (g_use_unix_socket)
768
  if (g_use_unix_socket)
410
  {
769
  {
411
    g_lis_trans = trans_create(2, 8192, 8192);
770
    tc_t mattr;
771
    tc_p pattr = &mattr;
772
    g_memset(pattr,0,sizeof(tc_t));
773
    TC_MUTATTR_INIT(pattr);
774
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
775
    TC_MUTATTR_SETPSHARED(pattr,TC_PROCESS_SHARED);
776
    g_lis_trans = trans_create(2, MAX_STREAM, MAX_STREAM);
777
    g_lis_trans->lock = (tc_p)g_malloc(sizeof(tc_t), 1);
778
    TC_MUTEX_INIT(g_lis_trans->lock, pattr);
412
    g_snprintf(port, 255, "/tmp/xrdp_chansrv_socket_%d", 7200 + g_display_num);
779
    g_snprintf(port, 255, "/tmp/xrdp_chansrv_socket_%d", 7200 + g_display_num);
413
  }
780
  }
414
  else
781
  else
415
  {
782
  {
416
    g_lis_trans = trans_create(1, 8192, 8192);
783
    tc_t mattr;
784
    tc_p pattr = &mattr;
785
    g_memset(pattr,0,sizeof(tc_t));
786
    TC_MUTATTR_INIT(pattr);
787
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
788
    TC_MUTATTR_SETPSHARED(pattr,TC_PROCESS_SHARED);
789
    g_lis_trans = trans_create(1, MAX_STREAM, MAX_STREAM);
790
    g_lis_trans->lock = (tc_p)g_malloc(sizeof(tc_t), 1);
791
    TC_MUTEX_INIT(g_lis_trans->lock, pattr);
417
    g_snprintf(port, 255, "%d", 7200 + g_display_num);
792
    g_snprintf(port, 255, "%d", 7200 + g_display_num);
418
  }
793
  }
794
  TC_MUTEX_LOCK(g_lis_trans->lock);
419
  g_lis_trans->trans_conn_in = my_trans_conn_in;
795
  g_lis_trans->trans_conn_in = my_trans_conn_in;
420
  error = trans_listen(g_lis_trans, port);
796
  error = trans_listen(g_lis_trans, port);
797
  TC_MUTEX_UNLOCK(g_lis_trans->lock);
798
  TC_MUTEX_UNLOCK(mutex_event);
421
  if (error != 0)
799
  if (error != 0)
422
  {
800
  {
423
    LOG(0, ("setup_listen: trans_listen failed for port %s", port));
801
    LOG(0, ("setup_listen: trans_listen failed for port %s", port));
424
    return 1;
802
    MDBGLOG("chansrv", "ERROR\t[%s()]: trans_listen() failed for port \"%s\"", __func__, port);
803
    res = 1;
425
  }
804
  }
426
  return 0;
805
  return res;
427
}
806
}
428
807
429
/*****************************************************************************/
808
/*****************************************************************************/
430
THREAD_RV THREAD_CC
809
THREAD_RV THREAD_CC
431
channel_thread_loop(void* in_val)
810
channel_thread_loop(void* in_val)
432
{
811
{
433
  tbus objs[32];
812
  tbus objs[64];
434
  int num_objs;
813
  int num_objs = 0;
435
  int timeout;
814
  int timeout = 0;
436
  int error;
815
  int error = 0;
437
  THREAD_RV rv;
816
  int elocked = 0;
817
  int mlocked = 0;
818
  THREAD_RV rv = 0;
438
819
439
  LOG(1, ("channel_thread_loop: thread start"));
820
  LOG(1, ("channel_thread_loop: thread start"));
821
  MDBGLOG("chansrv", "INFO\t[%s()]: thread start [pid = %d, tid = %d]", __func__,g_getpid(),g_gettid());
822
823
  g_memset(objs,0,sizeof(objs));
440
  rv = 0;
824
  rv = 0;
825
826
  TC_MUTEX_LOCK(mutex_chan);
827
  mlocked = 1;
441
  error = setup_listen();
828
  error = setup_listen();
442
  if (error == 0)
829
  if (error == 0)
443
  {
830
  {
444
    timeout = 0;
831
    timeout = 0;
445
    num_objs = 0;
832
    num_objs = 0;
833
834
    TC_MUTEX_LOCK(mutex_event);
835
    elocked = 1;
446
    objs[num_objs] = g_term_event;
836
    objs[num_objs] = g_term_event;
447
    num_objs++;
837
    num_objs++;
448
    trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
838
    if (g_lis_trans != NULL && g_lis_trans->lock != NULL) {
839
      TC_MUTEX_LOCK(g_lis_trans->lock);
840
      trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
841
      TC_MUTEX_UNLOCK(g_lis_trans->lock);
842
    }
843
    else if (g_lis_trans != NULL) {
844
      trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
845
    }
846
    TC_MUTEX_UNLOCK(mutex_event);
847
    elocked = 0;
848
849
    TC_MUTEX_UNLOCK(mutex_chan);
850
    mlocked = 0;
851
449
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0)
852
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0)
450
    {
853
    {
451
      if (g_is_wait_obj_set(g_term_event))
854
      if (g_is_wait_obj_set(g_term_event))
452
      {
855
      {
453
        LOG(0, ("channel_thread_loop: g_term_event set"));
856
        LOG(0, ("channel_thread_loop: g_term_event set"));
857
        MDBGLOG("chansrv", "INFO\t[%s()]: g_term_event set", __func__);
858
454
        clipboard_deinit();
859
        clipboard_deinit();
455
        sound_deinit();
860
        sound_deinit();
456
        dev_redir_deinit();
861
	rdpdr_deinit();
457
        break;
862
	drdynvc_deinit();
863
864
	break;
458
      }
865
      }
866
      TC_MUTEX_LOCK(mutex_event);
459
      if (g_lis_trans != 0)
867
      if (g_lis_trans != 0)
460
      {
868
      {
869
	TC_MUTEX_UNLOCK(mutex_event);
461
        if (trans_check_wait_objs(g_lis_trans) != 0)
870
        if (trans_check_wait_objs(g_lis_trans) != 0)
462
        {
871
        {
463
          LOG(0, ("channel_thread_loop: trans_check_wait_objs error"));
872
          LOG(0, ("channel_thread_loop: trans_check_wait_objs error"));
873
	  MDBGLOG("chansrv", "WARNING\t[%s()]: ERROR in trans_check_wait_objs()", __func__);
464
        }
874
        }
875
	TC_MUTEX_LOCK(mutex_event);
465
      }
876
      }
466
      if (g_con_trans != 0)
877
      if (g_con_trans != 0)
467
      {
878
      {
468
        if (trans_check_wait_objs(g_con_trans) != 0)
879
	int tres = 0;
880
	TC_MUTEX_UNLOCK(mutex_event);
881
	tres = trans_check_wait_objs(g_con_trans);
882
        if (tres != 0)
469
        {
883
        {
470
          LOG(0, ("channel_thread_loop: "
884
471
                  "trans_check_wait_objs error resetting"));
885
          LOG(0, ("channel_thread_loop: trans_check_wait_objs error resetting"));
886
          MDBGLOG("chansrv","WARNING\t[%s()]: trans_check_wait_objs() returned error 0x%8.8x; now resetting", __func__, tres);
887
472
          clipboard_deinit();
888
          clipboard_deinit();
473
          sound_deinit();
889
          sound_deinit();
474
          dev_redir_deinit();
890
          rdpdr_deinit();
891
          drdynvc_deinit();
892
893
	  TC_MUTEX_LOCK(mutex_chan);
894
	  mlocked = 1;
895
475
          /* delete g_con_trans */
896
          /* delete g_con_trans */
476
          trans_delete(g_con_trans);
897
	  TC_MUTEX_LOCK(mutex_event);
477
          g_con_trans = 0;
898
	  elocked = 1;
899
	  if (g_con_trans != 0) {
900
	    unsigned char tlock = 0;
901
	    if (g_con_trans->lock != NULL) {
902
	      TC_MUTEX_LOCK(g_con_trans->lock);
903
	      tlock = 1;
904
	    }
905
            trans_delete(g_con_trans);
906
	    if (tlock > 0) {
907
	      TC_MUTEX_UNLOCK(g_con_trans->lock);
908
	    }
909
            g_con_trans = 0;
910
	  }
911
	  TC_MUTEX_UNLOCK(mutex_event);
912
	  elocked = 0;
478
          /* create new listener */
913
          /* create new listener */
479
          error = setup_listen();
914
          error = setup_listen();
915
916
	  TC_MUTEX_UNLOCK(mutex_chan);
917
	  mlocked = 0;
918
480
          if (error != 0)
919
          if (error != 0)
481
          {
920
          {
482
            break;
921
            break;
483
          }
922
          }
484
        }
923
        }
485
      }
924
      }
925
      else {
926
	TC_MUTEX_UNLOCK(mutex_event);
927
      }
928
486
      clipboard_check_wait_objs();
929
      clipboard_check_wait_objs();
487
      sound_check_wait_objs();
930
      sound_check_wait_objs();
488
      dev_redir_check_wait_objs();
931
      rdpdr_check_wait_objs();
932
      drdynvc_check_wait_objs();
933
934
      TC_MUTEX_LOCK(mutex_chan);
935
      mlocked = 1;
936
489
      timeout = 0;
937
      timeout = 0;
490
      num_objs = 0;
938
      num_objs = 0;
939
      TC_MUTEX_LOCK(mutex_event);
940
      elocked = 1;
491
      objs[num_objs] = g_term_event;
941
      objs[num_objs] = g_term_event;
492
      num_objs++;
942
      num_objs++;
493
      trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
943
      {
494
      trans_get_wait_objs(g_con_trans, objs, &num_objs, &timeout);
944
	unsigned char tlock = 0;
945
	if (g_lis_trans != NULL && g_lis_trans->lock != NULL) {
946
          TC_MUTEX_LOCK(g_lis_trans->lock);
947
	  tlock = 1;
948
	}
949
        trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
950
	if (tlock > 0) {
951
          TC_MUTEX_UNLOCK(g_lis_trans->lock);
952
	}
953
	tlock = 0;
954
	if (g_con_trans != NULL && g_con_trans->lock != NULL) {
955
          TC_MUTEX_LOCK(g_con_trans->lock);
956
	  tlock = 1;
957
	}
958
        trans_get_wait_objs(g_con_trans, objs, &num_objs, &timeout);
959
	if (tlock > 0) {
960
          TC_MUTEX_UNLOCK(g_con_trans->lock);
961
	}
962
      }
963
      TC_MUTEX_UNLOCK(mutex_event);
964
      elocked = 0;
495
      clipboard_get_wait_objs(objs, &num_objs, &timeout);
965
      clipboard_get_wait_objs(objs, &num_objs, &timeout);
496
      sound_get_wait_objs(objs, &num_objs, &timeout);
966
      sound_get_wait_objs(objs, &num_objs, &timeout);
497
      dev_redir_get_wait_objs(objs, &num_objs, &timeout);
967
      rdpdr_get_wait_objs(objs, &num_objs, &timeout);
968
      drdynvc_get_wait_objs(objs, &num_objs, &timeout);
969
970
      TC_MUTEX_UNLOCK(mutex_chan);
971
      mlocked = 0;
498
    }
972
    }
499
  }
973
  }
500
  trans_delete(g_lis_trans);
974
  else if (mlocked > 0) {
975
    TC_MUTEX_UNLOCK(mutex_chan);
976
    mlocked = 0;
977
  }
978
979
  TC_MUTEX_LOCK(mutex_chan);
980
  mlocked = 1;
981
982
  TC_MUTEX_LOCK(mutex_event);
983
  elocked = 1;
984
  if (g_lis_trans != NULL && g_lis_trans->lock != NULL) {
985
    TC_MUTEX_LOCK(g_lis_trans->lock);
986
    trans_delete(g_lis_trans);
987
    TC_MUTEX_UNLOCK(g_lis_trans->lock);
988
  }
989
  else if (g_lis_trans != NULL) {
990
    trans_delete(g_lis_trans);
991
  }
501
  g_lis_trans = 0;
992
  g_lis_trans = 0;
502
  trans_delete(g_con_trans);
993
994
  if (g_con_trans != NULL && g_con_trans->lock != NULL) {
995
    TC_MUTEX_LOCK(g_con_trans->lock);
996
    trans_delete(g_con_trans);
997
    TC_MUTEX_UNLOCK(g_con_trans->lock);
998
  }
999
  else if (g_con_trans != NULL) {
1000
    trans_delete(g_con_trans);
1001
  }
503
  g_con_trans = 0;
1002
  g_con_trans = 0;
1003
504
  LOG(0, ("channel_thread_loop: thread stop"));
1004
  LOG(0, ("channel_thread_loop: thread stop"));
1005
  MDBGLOG("chansrv", "SIGNAL\t[%s()]: thread stop", __func__);
505
  g_set_wait_obj(g_thread_done_event);
1006
  g_set_wait_obj(g_thread_done_event);
1007
  TC_MUTEX_UNLOCK(mutex_event);
1008
  elocked = 0;
1009
1010
  TC_MUTEX_UNLOCK(mutex_chan);
1011
  mlocked = 0;
1012
506
  return rv;
1013
  return rv;
507
}
1014
}
508
1015
 Lines 510-575    Link Here 
510
void DEFAULT_CC
1017
void DEFAULT_CC
511
term_signal_handler(int sig)
1018
term_signal_handler(int sig)
512
{
1019
{
513
  LOG(1, ("term_signal_handler: got signal %d", sig));
1020
  //LOG(1, ("term_signal_handler: got signal %d", sig));
1021
  MDBGLOG("chansrv", "SIGNAL\t[%s()]: received signal %d", __func__, sig);
1022
  //TC_MUTEX_LOCK(mutex_event);
514
  g_set_wait_obj(g_term_event);
1023
  g_set_wait_obj(g_term_event);
1024
  //TC_MUTEX_UNLOCK(mutex_event);
515
}
1025
}
516
1026
517
/*****************************************************************************/
1027
/*****************************************************************************/
518
void DEFAULT_CC
1028
void DEFAULT_CC
519
nil_signal_handler(int sig)
1029
nil_signal_handler(int sig)
520
{
1030
{
521
  LOG(1, ("nil_signal_handler: got signal %d", sig));
1031
  //LOG(1, ("nil_signal_handler: got signal %d", sig));
1032
  MDBGLOG("chansrv", "SIGNAL\t[%s()]: received signal %d", __func__, sig);
522
}
1033
}
523
1034
524
/*****************************************************************************/
1035
/*****************************************************************************/
525
static int APP_CC
1036
static int APP_CC
526
get_display_num_from_display(char* display_text)
1037
get_display_num_from_display(char * display_text)
527
{
1038
{
528
  int index;
1039
  ptrdiff_t index = 0;
529
  int mode;
1040
  int mode = 0;
530
  int host_index;
1041
  ptrdiff_t host_index = 0;
531
  int disp_index;
1042
  ptrdiff_t disp_index = 0;
532
  int scre_index;
1043
  ptrdiff_t scre_index = 0;
533
  char host[256];
1044
  char host[256] = "";
534
  char disp[256];
1045
  char disp[256] = "";
535
  char scre[256];
1046
  char scre[256] = "";
536
1047
  ptrdiff_t bcnt = 0;
537
  index = 0;
1048
  ptrdiff_t ccnt = 0;
538
  host_index = 0;
1049
  ptrdiff_t first_brack_pos = 0;
539
  disp_index = 0;
1050
  ptrdiff_t final_brack_pos = 0;
540
  scre_index = 0;
1051
  ptrdiff_t final_colon_pos = 0;
541
  mode = 0;
1052
  ptrdiff_t final_dot_pos = 0;
542
  while (display_text[index] != 0)
1053
  char * tmp = (char *)NULL;
543
  {
1054
  char * pch = (char *)NULL;
544
    if (display_text[index] == ':')
1055
  char * first_brack = (char *)NULL;
545
    {
1056
  char * final_brack = (char *)NULL;
546
      mode = 1;
1057
  char * final_colon = (char *)NULL;
1058
  char * final_dot = (char *)NULL;
1059
1060
  g_memset(host,0,256);
1061
  g_memset(disp,0,256);
1062
  g_memset(scre,0,256);
1063
1064
  if (display_text[0] == '[') {
1065
    first_brack_pos = 1;
1066
    final_brack = strrchr(display_text, ']');
1067
    if (final_brack != NULL) {
1068
      final_brack_pos = final_brack - display_text + 1;
547
    }
1069
    }
548
    else if (display_text[index] == '.')
1070
  }
549
    {
1071
550
      mode = 2;
1072
  final_colon = strrchr(display_text, ':');
551
    }
1073
  if (final_colon != NULL) {
552
    else if (mode == 0)
1074
    final_colon_pos = (final_colon - display_text) + 1;
553
    {
1075
  }
554
      host[host_index] = display_text[index];
1076
555
      host_index++;
1077
  final_dot = strrchr(final_colon, '.');
556
    }
1078
  if (final_dot != NULL) {
557
    else if (mode == 1)
1079
    final_dot_pos = (final_dot - display_text) + 1;
558
    {
1080
  }
559
      disp[disp_index] = display_text[index];
1081
560
      disp_index++;
1082
  if (final_colon_pos > 1) {
1083
    g_snprintf(host, (final_colon_pos - 1), "%s", display_text);
1084
  }
1085
1086
  if (final_colon != NULL) {
1087
    if (((final_dot_pos > 0) && (final_colon_pos > 0)) && ((final_dot_pos - (final_colon_pos + 1)) > 1)) {
1088
      g_snprintf(disp, (final_dot_pos - final_colon_pos), "%s", final_colon + 1);
561
    }
1089
    }
562
    else if (mode == 2)
1090
    if (final_dot_pos > 0) {
563
    {
1091
      g_sprintf(scre, "%s", final_dot + 1);
564
      scre[scre_index] = display_text[index];
565
      scre_index++;
566
    }
1092
    }
567
    index++;
568
  }
1093
  }
569
  host[host_index] = 0;
1094
570
  disp[disp_index] = 0;
1095
  TC_MUTEX_LOCK(mutex_event);
571
  scre[scre_index] = 0;
572
  g_display_num = g_atoi(disp);
1096
  g_display_num = g_atoi(disp);
1097
  TC_MUTEX_UNLOCK(mutex_event);
573
  return 0;
1098
  return 0;
574
}
1099
}
575
1100
 Lines 577-584    Link Here 
577
int APP_CC
1102
int APP_CC
578
main_cleanup(void)
1103
main_cleanup(void)
579
{
1104
{
1105
  TC_MUTEX_LOCK(mutex_event);
580
  g_delete_wait_obj(g_term_event);
1106
  g_delete_wait_obj(g_term_event);
581
  g_delete_wait_obj(g_thread_done_event);
1107
  g_delete_wait_obj(g_thread_done_event);
1108
  TC_MUTEX_UNLOCK(mutex_event);
582
  g_deinit(); /* os_calls */
1109
  g_deinit(); /* os_calls */
583
  return 0;
1110
  return 0;
584
}
1111
}
 Lines 587-620    Link Here 
587
static int APP_CC
1114
static int APP_CC
588
read_ini(void)
1115
read_ini(void)
589
{
1116
{
590
  char filename[256];
1117
  char filename[256] = "";
591
  struct list* names;
1118
  struct list* names = (struct list *)NULL;
592
  struct list* values;
1119
  struct list* values = (struct list *)NULL;
593
  char* name;
1120
  char* name = (char *)NULL;
594
  char* value;
1121
  char* value = (char *)NULL;
595
  int index;
1122
  ptrdiff_t index = 0;
1123
1124
  g_memset(filename,0,(sizeof(char) * 256));
596
1125
597
  names = list_create();
1126
  names = list_create();
598
  names->auto_free = 1;
1127
  names->auto_free = 1;
599
  values = list_create();
1128
  values = list_create();
600
  values->auto_free = 1;
1129
  values->auto_free = 1;
1130
1131
  TC_MUTEX_LOCK(mutex_chan);
1132
601
  g_use_unix_socket = 0;
1133
  g_use_unix_socket = 0;
602
  g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH);
1134
  g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH);
603
  if (file_by_name_read_section(filename, "Globals", names, values) == 0)
1135
  if (file_by_name_read_section(filename, "Globals", names, values) == 0) {
604
  {
1136
    for (index = 0; index < names->count; index++) {
605
    for (index = 0; index < names->count; index++)
606
    {
607
      name = (char*)list_get_item(names, index);
1137
      name = (char*)list_get_item(names, index);
608
      value = (char*)list_get_item(values, index);
1138
      value = (char*)list_get_item(values, index);
609
      if (g_strcasecmp(name, "ListenAddress") == 0)
1139
      if (g_strcasecmp(name, "ListenAddress") == 0) {
610
      {
1140
	if ((value == NULL) || (g_strlen(value) < 1) || (g_strcasecmp(value, "socket") == 0) || (g_strcasecmp(value, "localhost") == 0) || (g_strcasecmp(value, "") == 0) || (g_strchr(value, '/') != NULL)) {
611
        if (g_strcasecmp(value, "127.0.0.1") == 0)
1141
	  g_use_unix_socket = 1;
612
        {
1142
	}
613
          g_use_unix_socket = 1;
614
        }
615
      }
1143
      }
616
    }
1144
    }
617
  }
1145
  }
1146
1147
  TC_MUTEX_UNLOCK(mutex_chan);
1148
618
  list_delete(names);
1149
  list_delete(names);
619
  list_delete(values);
1150
  list_delete(values);
620
  return 0;
1151
  return 0;
 Lines 624-656    Link Here 
624
int DEFAULT_CC
1155
int DEFAULT_CC
625
main(int argc, char** argv)
1156
main(int argc, char** argv)
626
{
1157
{
627
  int pid;
1158
  int pid = 0;
628
  char text[256];
1159
  char text[256] = "";
629
  char* display_text;
1160
  char* display_text = (char *)NULL;
1161
  char* username_text = (char *)NULL;
1162
  glob_t pglob;
1163
  ptrdiff_t idx = 0;
1164
  unsigned char elocked = 0;
1165
  uid_t tuid = 0;
1166
  gid_t tgid = 0;
1167
  struct passwd * pw = (struct passwd *)NULL;
1168
1169
  g_attr = &g_mutattr;
1170
  g_memset(g_attr,0,sizeof(tc_t));
1171
  TC_MUTATTR_INIT(g_attr);
1172
  TC_MUTATTR_SETTYPE(g_attr, TC_MUTEX_ERRORCHECK);
1173
  TC_MUTATTR_SETPSHARED(g_attr, TC_PROCESS_SHARED);
1174
1175
  TC_MUTEX_INIT(mutex_event, g_attr);
1176
  TC_MUTEX_INIT(mutex_mem, g_attr);
1177
1178
  g_memset(text,0,sizeof(char) * 256);
1179
  g_memset(&pglob,0,sizeof(glob_t));
1180
1181
  if (mutex_chan == NULL) {
1182
    tc_t mattr;
1183
    tc_p pattr = &mattr;
1184
    g_memset(pattr,0,sizeof(tc_t));
1185
    TC_MUTATTR_INIT(pattr);
1186
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1187
    TC_MUTATTR_SETPSHARED(pattr,TC_PROCESS_SHARED);
1188
    TC_MUTEX_INIT(mutex_chan,pattr);
1189
    TC_MUTEX_INIT(&g_out_mutex,pattr);
1190
  }
1191
  TC_MUTEX_LOCK(mutex_chan);
630
1192
631
  g_init(); /* os_calls */
1193
  g_init(); /* os_calls */
632
  read_ini();
1194
  read_ini();
633
  pid = g_getpid();
1195
  pid = g_getpid();
1196
634
  LOG(1, ("main: app started pid %d(0x%8.8x)", pid, pid));
1197
  LOG(1, ("main: app started pid %d(0x%8.8x)", pid, pid));
1198
  MDBGLOG("chansrv", "INFO\t[%s()]: xrdp-chansrv started (pid = %d)", __func__, pid);
1199
1200
  /*	set up signal handlers	*/
635
  g_signal_kill(term_signal_handler); /* SIGKILL */
1201
  g_signal_kill(term_signal_handler); /* SIGKILL */
636
  g_signal_terminate(term_signal_handler); /* SIGTERM */
1202
  g_signal_terminate(term_signal_handler); /* SIGTERM */
637
  g_signal_user_interrupt(term_signal_handler); /* SIGINT */
1203
  g_signal_user_interrupt(term_signal_handler); /* SIGINT */
638
  g_signal_pipe(nil_signal_handler); /* SIGPIPE */
1204
  g_signal_pipe(nil_signal_handler); /* SIGPIPE */
1205
1206
  glob("/tmp/taskq_*.log",GLOB_NOSORT,NULL,&pglob);
1207
  for (idx = 0; idx < pglob.gl_pathc; idx++) {
1208
    unlink(pglob.gl_pathv[idx]);
1209
  }
1210
1211
  username_text = g_getenv("USER");
639
  display_text = g_getenv("DISPLAY");
1212
  display_text = g_getenv("DISPLAY");
1213
1214
  pw = getpwnam((const char *)username_text);
1215
  tuid = pw->pw_uid;
1216
  tgid = pw->pw_gid;
1217
  setgid(tgid);
1218
  setuid(tuid);
1219
640
  LOG(1, ("main: DISPLAY env var set to %s", display_text));
1220
  LOG(1, ("main: DISPLAY env var set to %s", display_text));
1221
  MDBGLOG("chansrv", "INFO\t[%s()]: DISPLAY env var set to \"%s\"", __func__, display_text);
641
  get_display_num_from_display(display_text);
1222
  get_display_num_from_display(display_text);
642
  if (g_display_num == 0)
1223
  TC_MUTEX_LOCK(mutex_event);
643
  {
1224
  if (g_display_num == 0) {
644
    LOG(0, ("main: error, display is zero"));
1225
    LOG(0, ("main: error, display is zero"));
1226
    TC_MUTEX_UNLOCK(mutex_event);
645
    return 1;
1227
    return 1;
646
  }
1228
  }
647
  LOG(1, ("main: using DISPLAY %d", g_display_num));
1229
  LOG(1, ("main: using DISPLAY %d", g_display_num));
1230
  MDBGLOG("chansrv", "INFO\t[%s()]: using DISPLAY \"%d\"", __func__, g_display_num);
648
  g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid);
1231
  g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid);
649
  g_term_event = g_create_wait_obj(text);
1232
  g_term_event = g_create_wait_obj(text);
650
  g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid);
1233
  g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid);
651
  g_thread_done_event = g_create_wait_obj(text);
1234
  g_thread_done_event = g_create_wait_obj(text);
1235
  TC_MUTEX_UNLOCK(mutex_event);
1236
1237
  {
1238
  char tpid[6] = "";
1239
  g_snprintf(tpid,6,"%d",g_getpid());
1240
  g_setenv("PULSE_PROP_application.name","xrdp",1);
1241
  g_setenv("PULSE_PROP_application.icon_name","xrdp",1);
1242
  g_setenv("PULSE_PROP_media.role","event",1);
1243
  g_setenv("PULSE_PROP_application.process.user",username_text,1);
1244
  g_setenv("PULSE_PROP_application.process.id",tpid,1);
1245
  g_setenv("PULSE_PROP_application.process.binary","xrdp-chansrv",1);
1246
  g_setenv("PULSE_PROP_window.x11.display",display_text,1);
1247
  }
1248
1249
1250
  g_iconv_init();
1251
1252
  TC_MUTEX_UNLOCK(mutex_chan);
1253
652
  tc_thread_create(channel_thread_loop, 0);
1254
  tc_thread_create(channel_thread_loop, 0);
653
  while (!g_is_wait_obj_set(g_term_event))
1255
  MDBGLOG("chansrv","INFO\t[%s()]: locked <mutex_event>.",__func__);
1256
  while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event))
654
  {
1257
  {
655
    if (g_obj_wait(&g_term_event, 1, 0, 0, 0) != 0)
1258
    if (g_obj_wait(&g_term_event, 1, 0, 0, 0) != 0)
656
    {
1259
    {
 Lines 658-664    Link Here 
658
      break;
1261
      break;
659
    }
1262
    }
660
  }
1263
  }
661
  while (!g_is_wait_obj_set(g_thread_done_event))
1264
  while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event))
662
  {
1265
  {
663
    /* wait for thread to exit */
1266
    /* wait for thread to exit */
664
    if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0)
1267
    if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0)
 Lines 667-674    Link Here 
667
      break;
1270
      break;
668
    }
1271
    }
669
  }
1272
  }
1273
1274
  TC_MUTEX_LOCK(mutex_chan);
1275
1276
  g_iconv_end();
670
  /* cleanup */
1277
  /* cleanup */
671
  main_cleanup();
1278
  main_cleanup();
1279
1280
  TC_MUTEX_UNLOCK(mutex_chan);
1281
672
  LOG(1, ("main: app exiting pid %d(0x%8.8x)", pid, pid));
1282
  LOG(1, ("main: app exiting pid %d(0x%8.8x)", pid, pid));
673
  return 0;
1283
  return 0;
674
}
1284
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/chansrv.h (-6 / +29 lines)
 Lines 2-9    Link Here 
2
#if !defined(CHANSRV_H)
2
#if !defined(CHANSRV_H)
3
#define CHANSRV_H
3
#define CHANSRV_H
4
4
5
#include <stddef.h>
6
#include <stdio.h>
5
#include "arch.h"
7
#include "arch.h"
6
#include "parse.h"
8
#include "parse.h"
9
#include "thread_calls.h"
10
#include "thread_macros.h"
11
#include "dbg.h"
7
12
8
struct chan_item
13
struct chan_item
9
{
14
{
 Lines 12-24    Link Here 
12
  char name[16];
17
  char name[16];
13
};
18
};
14
19
15
int APP_CC
20
ptrdiff_t APP_CC send_channel_data(int, char *, size_t);
16
send_channel_data(int chan_id, char* data, int size);
21
ptrdiff_t APP_CC send_channel_data_multiple_atomic(int, unsigned int, char * [], size_t []);
17
int APP_CC
22
int APP_CC main_cleanup(void);
18
main_cleanup(void);
19
20
#define LOG_LEVEL 5
21
23
24
#define LOG_LEVEL 255
22
#define LOG(_a, _params) \
25
#define LOG(_a, _params) \
23
{ \
26
{ \
24
  if (_a < LOG_LEVEL) \
27
  if (_a < LOG_LEVEL) \
 Lines 28-31    Link Here 
28
  } \
31
  } \
29
}
32
}
30
33
34
#define OLDDBGLOG(_itxt) \
35
{ \
36
  int taskq = 0; \
37
  char taskq_text[256]; \
38
  if (taskq == 0) \
39
  { \
40
    g_file_delete("/tmp/taskq.log"); \
41
    taskq = g_file_open("/tmp/taskq.log"); \
42
  } \
43
  g_snprintf(taskq_text, _itxt, 255 ); \
44
  g_lfile_writeln(taskq, "---"); \
45
  g_lfile_write(taskq, taskq_text); \
46
}
47
48
unsigned int taskq_count;
49
void DBGLOG(const char *, const char *);
50
51
tc_t            g_chan_mutex;
52
tc_p            mutex_chan;
53
31
#endif
54
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/clipboard.c (-133 / +227 lines)
 Lines 22-31    Link Here 
22
22
23
*/
23
*/
24
24
25
#include <stddef.h>
25
#include <X11/Xlib.h>
26
#include <X11/Xlib.h>
26
#include <X11/Xatom.h>
27
#include <X11/Xatom.h>
27
#include <X11/extensions/Xfixes.h>
28
#include <X11/extensions/Xfixes.h>
28
#include "arch.h"
29
#include "arch.h"
30
#include "defines.h"
29
#include "parse.h"
31
#include "parse.h"
30
#include "os_calls.h"
32
#include "os_calls.h"
31
#include "chansrv.h"
33
#include "chansrv.h"
 Lines 39-70    Link Here 
39
static Atom g_secondary_atom = 0;
41
static Atom g_secondary_atom = 0;
40
static Atom g_get_time_atom = 0;
42
static Atom g_get_time_atom = 0;
41
static Atom g_utf8_atom = 0;
43
static Atom g_utf8_atom = 0;
42
static int g_x_socket = 0;
44
static tbus g_x_socket = 0;
43
static tbus g_x_wait_obj = 0;
45
static tbus g_x_wait_obj = 0;
44
static int g_clip_up = 0;
46
static unsigned char g_clip_up = 0;
45
static Window g_wnd = 0;
47
static Window g_wnd = 0;
46
static Screen* g_screen = 0;
48
static Screen* g_screen = 0;
47
static int g_screen_num = 0;
49
static int g_screen_num = 0;
48
static int g_xfixes_event_base = 0;
50
static size_t g_xfixes_event_base = 0;
49
51
50
static int g_last_clip_size = 0;
52
static size_t g_last_clip_size = 0;
51
static char* g_last_clip_data = 0;
53
static char* g_last_clip_data = 0;
52
static Atom g_last_clip_type = 0;
54
static Atom g_last_clip_type = 0;
53
55
54
static int g_got_selection = 0; /* boolean */
56
static unsigned char g_got_selection = 0; /* boolean */
55
static Time g_selection_time = 0;
57
static Time g_selection_time = 0;
56
58
57
static struct stream* g_ins = 0;
59
static struct stream * g_ins = 0;
58
60
59
static XSelectionRequestEvent g_selection_request_event[16];
61
static XSelectionRequestEvent g_selection_request_event[16];
60
static int g_selection_request_event_count = 0;
62
static size_t g_selection_request_event_count = 0;
61
63
62
static char* g_data_in = 0;
64
static char* g_data_in = 0;
63
static int g_data_in_size = 0;
65
static size_t g_data_in_size = 0;
64
static int g_data_in_time = 0;
66
static int g_data_in_time = 0;
65
static int g_data_in_up_to_date = 0;
67
static int g_data_in_up_to_date = 0;
66
static int g_got_format_announce = 0;
68
static unsigned char g_got_format_announce = 0;
67
static int g_waiting_for_data_response = 0;
69
static unsigned char g_waiting_for_data_response = 0;
68
static int g_waiting_for_data_response_time = 0;
70
static int g_waiting_for_data_response_time = 0;
69
71
70
static Display* g_display = 0;
72
static Display* g_display = 0;
 Lines 75-81    Link Here 
75
int DEFAULT_CC
77
int DEFAULT_CC
76
clipboard_error_handler(Display* dis, XErrorEvent* xer)
78
clipboard_error_handler(Display* dis, XErrorEvent* xer)
77
{
79
{
78
  char text[256];
80
  char text[256] = "";
79
81
80
  XGetErrorText(dis, xer->error_code, text, 255);
82
  XGetErrorText(dis, xer->error_code, text, 255);
81
  LOG(1, ("error [%s]", text));
83
  LOG(1, ("error [%s]", text));
 Lines 101-106    Link Here 
101
{
103
{
102
  XEvent xevent;
104
  XEvent xevent;
103
105
106
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_server_time() called");
104
  /* append nothing */
107
  /* append nothing */
105
  XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8,
108
  XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8,
106
                  PropModeAppend, "", 0);
109
                  PropModeAppend, "", 0);
 Lines 113-125    Link Here 
113
}
116
}
114
117
115
/*****************************************************************************/
118
/*****************************************************************************/
116
/* returns time in miliseconds
119
/* returns time in milliseconds
117
   this is like g_time2 in os_calls, but not miliseconds since machine was
120
   this is like g_time2 in os_calls, but not milliseconds since machine was
118
   up, something else
121
   up, something else
119
   this is a time value similar to what the xserver uses */
122
   this is a time value similar to what the xserver uses */
120
static int APP_CC
123
static int APP_CC
121
clipboard_get_local_time(void)
124
clipboard_get_local_time(void)
122
{
125
{
126
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_local_time() called");
123
  return g_time3();
127
  return g_time3();
124
}
128
}
125
129
 Lines 128-143    Link Here 
128
int APP_CC
132
int APP_CC
129
clipboard_init(void)
133
clipboard_init(void)
130
{
134
{
131
  struct stream* s;
135
  int rv = 0;
132
  int size;
136
  struct stream* s = (struct stream *)NULL;
133
  int rv;
137
  size_t size = 0;
134
  int input_mask;
138
  int input_mask = 0;
135
  int dummy;
139
  int dummy = 0;
136
  int ver_maj;
140
  int ver_maj = 0;
137
  int ver_min;
141
  int ver_min = 0;
138
  Status st;
142
  Status st;
139
143
140
  LOG(5, ("xrdp-chansrv: in clipboard_init"));
144
  g_memset(&st,0,sizeof(Status));
145
146
  LOG(5, ("[xrdp-chansrv]->clipboard_init() called"));
147
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_init() called");
141
  if (g_clip_up)
148
  if (g_clip_up)
142
  {
149
  {
143
    return 0;
150
    return 0;
 Lines 151-157    Link Here 
151
  g_display = XOpenDisplay(0);
158
  g_display = XOpenDisplay(0);
152
  if (g_display == 0)
159
  if (g_display == 0)
153
  {
160
  {
154
    LOG(0, ("clipboard_init: XOpenDisplay failed"));
161
    LOG(0, ("[xrdp-chansrv]->clipboard_init(): XOpenDisplay failed"));
155
    rv = 1;
162
    rv = 1;
156
  }
163
  }
157
  if (rv == 0)
164
  if (rv == 0)
 Lines 162-168    Link Here 
162
      LOG(0, ("clipboard_init: XConnectionNumber failed"));
169
      LOG(0, ("clipboard_init: XConnectionNumber failed"));
163
      rv = 2;
170
      rv = 2;
164
    }
171
    }
165
    g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
172
    else {
173
      g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
174
    }
166
  }
175
  }
167
  if (rv == 0)
176
  if (rv == 0)
168
  {
177
  {
 Lines 177-191    Link Here 
177
  {
186
  {
178
    if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy))
187
    if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy))
179
    {
188
    {
180
      LOG(0, ("clipboard_init: no xfixes"));
189
      LOG(0, ("[xrdp-chansrv]->clipboard_init(): no xfixes"));
181
      rv = 5;
190
      rv = 5;
182
    }
191
    }
183
  }
192
  }
184
  if (rv == 0)
193
  if (rv == 0)
185
  {
194
  {
186
    LOG(0, ("clipboard_init: g_xfixes_event_base %d", g_xfixes_event_base));
195
    LOG(0, ("[xrdp-chansrv]->clipboard_init(): g_xfixes_event_base %d", g_xfixes_event_base));
187
    st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
196
    st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
188
    LOG(0, ("clipboard_init st %d, maj %d min %d", st, ver_maj, ver_min));
197
    LOG(0, ("[xrdp-chansrv]->clipboard_init(): st = %d; maj = %d; min = %d", st, ver_maj, ver_min));
189
    g_screen_num = DefaultScreen(g_display);
198
    g_screen_num = DefaultScreen(g_display);
190
    g_screen = ScreenOfDisplay(g_display, g_screen_num);
199
    g_screen = ScreenOfDisplay(g_display, g_screen_num);
191
    g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
200
    g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
 Lines 212-230    Link Here 
212
  if (rv == 0)
221
  if (rv == 0)
213
  {
222
  {
214
    make_stream(s);
223
    make_stream(s);
215
    init_stream(s, 8192);
224
    init_stream(s, MAX_STREAM);
216
    out_uint16_le(s, 1); /* CLIPRDR_CONNECT */
225
    out_uint16_le(s, 1); /* CLIPRDR_CONNECT */
217
    out_uint16_le(s, 0); /* status */
226
    out_uint16_le(s, 0); /* status */
218
    out_uint32_le(s, 0); /* length */
227
    out_uint32_le(s, 0); /* length */
219
    out_uint32_le(s, 0); /* extra 4 bytes ? */
228
    out_uint32_le(s, 0); /* extra 4 bytes ? */
220
    s_mark_end(s);
229
    s_mark_end(s);
221
    size = (int)(s->end - s->data);
230
    size = (int)(s->end - s->data);
222
    LOG(5, ("clipboard_init: data out, sending "
231
    LOG(5, ("[xrdp-chansrv]->clipboard_init(): data out, sending "
223
        "CLIPRDR_CONNECT (clip_msg_id = 1)"));
232
        "CLIPRDR_CONNECT (clip_msg_id = 1)"));
224
    rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
233
    rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
234
    LOG(5,("[xrdp-chansrv]->clipboard_init(): g_cliprdr_chan_id = %d",g_cliprdr_chan_id));
225
    if (rv != 0)
235
    if (rv != 0)
226
    {
236
    {
227
      LOG(0, ("clipboard_init: send_channel_data failed "
237
      LOG(0, ("[xrdp-chansrv]->clipboard_init(): send_channel_data failed "
228
          "rv = %d", rv));
238
          "rv = %d", rv));
229
      rv = 4;
239
      rv = 4;
230
    }
240
    }
 Lines 234-240    Link Here 
234
  {
244
  {
235
    g_clip_up = 1;
245
    g_clip_up = 1;
236
    make_stream(g_ins);
246
    make_stream(g_ins);
237
    init_stream(g_ins, 8192)
247
    init_stream(g_ins, MAX_STREAM)
238
  }
248
  }
239
  else
249
  else
240
  {
250
  {
 Lines 258-271    Link Here 
258
    g_wnd = 0;
268
    g_wnd = 0;
259
  }
269
  }
260
  g_x_socket = 0;
270
  g_x_socket = 0;
261
  g_free(g_last_clip_data);
271
  //g_free(g_last_clip_data);
262
  g_last_clip_data = 0;
272
  g_last_clip_data = 0;
263
  g_last_clip_size = 0;
273
  g_last_clip_size = 0;
264
  free_stream(g_ins);
274
  if (g_ins != 0) {
275
    //free_stream(g_ins);
276
  }
265
  g_ins = 0;
277
  g_ins = 0;
266
  if (g_display != 0)
278
  if (g_display != 0)
267
  {
279
  {
268
    XCloseDisplay(g_display);
280
    //XCloseDisplay(g_display);
269
    g_display = 0;
281
    g_display = 0;
270
  }
282
  }
271
  g_clip_up = 0;
283
  g_clip_up = 0;
 Lines 276-285    Link Here 
276
static int APP_CC
288
static int APP_CC
277
clipboard_send_data_request(void)
289
clipboard_send_data_request(void)
278
{
290
{
279
  struct stream* s;
291
  int rv = 0;
280
  int size;
292
  struct stream * s = (struct stream *)NULL;
281
  int rv;
293
  ptrdiff_t size = 0;
282
  int num_chars;
294
  size_t num_chars = 0;
283
295
284
  LOG(5, ("clipboard_send_data_request:"));
296
  LOG(5, ("clipboard_send_data_request:"));
285
  if (!g_got_format_announce)
297
  if (!g_got_format_announce)
 Lines 289-301    Link Here 
289
  }
301
  }
290
  g_got_format_announce = 0;
302
  g_got_format_announce = 0;
291
  make_stream(s);
303
  make_stream(s);
292
  init_stream(s, 8192);
304
  init_stream(s, MAX_STREAM);
293
  out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */
305
  out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */
294
  out_uint16_le(s, 0); /* status */
306
  out_uint16_le(s, 0); /* status */
295
  out_uint32_le(s, 4); /* length */
307
  out_uint32_le(s, 4); /* length */
296
  out_uint32_le(s, 0x0d);
308
  out_uint32_le(s, 0x0d);
297
  s_mark_end(s);
309
  s_mark_end(s);
298
  size = (int)(s->end - s->data);
310
  size = s->end - s->data;
299
  LOG(5, ("clipboard_send_data_request: data out, sending "
311
  LOG(5, ("clipboard_send_data_request: data out, sending "
300
      "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"));
312
      "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"));
301
  rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
313
  rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
 Lines 307-324    Link Here 
307
static int APP_CC
319
static int APP_CC
308
clipboard_send_format_ack(void)
320
clipboard_send_format_ack(void)
309
{
321
{
310
  struct stream* s;
322
  struct stream* s = (struct stream *)NULL;
311
  int size;
323
  ptrdiff_t size = 0;
312
  int rv;
324
  int rv = 0;
313
325
314
  make_stream(s);
326
  make_stream(s);
315
  init_stream(s, 8192);
327
  init_stream(s, MAX_STREAM);
316
  out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */
328
  out_uint16_le(s, 3); /* CLIPRDR_FORMAT_ACK */
317
  out_uint16_le(s, 1); /* status */
329
  out_uint16_le(s, 1); /* status */
318
  out_uint32_le(s, 0); /* length */
330
  out_uint32_le(s, 0); /* length */
319
  out_uint32_le(s, 0); /* extra 4 bytes ? */
331
  out_uint32_le(s, 0); /* extra 4 bytes ? */
320
  s_mark_end(s);
332
  s_mark_end(s);
321
  size = (int)(s->end - s->data);
333
  size = s->end - s->data;
322
  LOG(5, ("clipboard_send_format_ack: data out, sending "
334
  LOG(5, ("clipboard_send_format_ack: data out, sending "
323
      "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"));
335
      "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"));
324
  rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
336
  rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
 Lines 330-348    Link Here 
330
static int APP_CC
342
static int APP_CC
331
clipboard_send_format_announce(void)
343
clipboard_send_format_announce(void)
332
{
344
{
333
  struct stream* s;
345
  struct stream* s = (struct stream *)NULL;
334
  int size;
346
  ptrdiff_t size = 0;
335
  int rv;
347
  int rv = 0;
336
348
337
  make_stream(s);
349
  make_stream(s);
338
  init_stream(s, 8192);
350
  init_stream(s, MAX_STREAM);
339
  out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */
351
  out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */
340
  out_uint16_le(s, 0); /* status */
352
  out_uint16_le(s, 0); /* status */
341
  out_uint32_le(s, 0x90); /* length */
353
  out_uint32_le(s, 0x90); /* length */
342
  out_uint32_le(s, 0x0d); /* extra 4 bytes ? */
354
  out_uint32_le(s, 0x0d); /* extra 4 bytes ? */
343
  out_uint8s(s, 0x90);
355
  out_uint8s(s, 0x90);
344
  s_mark_end(s);
356
  s_mark_end(s);
345
  size = (int)(s->end - s->data);
357
  size = s->end - s->data;
346
  LOG(5, ("clipboard_send_format_announce: data out, sending "
358
  LOG(5, ("clipboard_send_format_announce: data out, sending "
347
      "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"));
359
      "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"));
348
  rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
360
  rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
 Lines 353-364    Link Here 
353
/*****************************************************************************/
365
/*****************************************************************************/
354
/* returns number of bytes written */
366
/* returns number of bytes written */
355
static int APP_CC
367
static int APP_CC
356
clipboard_out_unicode(struct stream* s, char* text, int num_chars)
368
clipboard_out_unicode(struct stream * s, char * text, size_t num_chars)
357
{
369
{
358
  int index;
370
  ptrdiff_t index = 0;
359
  int lnum_chars;
371
  size_t lnum_chars = 0;
360
  twchar* ltext;
372
  twchar * ltext = (twchar *)NULL;
361
373
374
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_out_unicode() called");
362
  if ((num_chars < 1) || (text == 0))
375
  if ((num_chars < 1) || (text == 0))
363
  {
376
  {
364
    return 0;
377
    return 0;
 Lines 376-382    Link Here 
376
    out_uint16_le(s, ltext[index]);
389
    out_uint16_le(s, ltext[index]);
377
    index++;
390
    index++;
378
  }
391
  }
379
  g_free(ltext);
392
  //g_free(ltext);
380
  return index * 2;
393
  return index * 2;
381
}
394
}
382
395
 Lines 384-395    Link Here 
384
static int APP_CC
397
static int APP_CC
385
clipboard_send_data_response(void)
398
clipboard_send_data_response(void)
386
{
399
{
387
  struct stream* s;
400
  int rv = 0;
388
  int size;
401
  struct stream* s = (struct stream *)NULL;
389
  int rv;
402
  ptrdiff_t size = 0;
390
  int num_chars;
403
  size_t num_chars = 0;
391
404
392
  LOG(10, ("clipboard_send_data_response:"));
405
  LOG(10, ("clipboard_send_data_response:"));
406
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_send_data_response() called");
393
  num_chars = 0;
407
  num_chars = 0;
394
  if (g_last_clip_data != 0)
408
  if (g_last_clip_data != 0)
395
  {
409
  {
 Lines 399-404    Link Here 
399
      if (num_chars < 0)
413
      if (num_chars < 0)
400
      {
414
      {
401
        LOG(0, ("clipboard_send_data_response: bad string"));
415
        LOG(0, ("clipboard_send_data_response: bad string"));
416
        //DBGLOG("clipboard","clipboard_send_data_response: bad string");
402
        num_chars = 0;
417
        num_chars = 0;
403
      }
418
      }
404
    }
419
    }
 Lines 414-424    Link Here 
414
  {
429
  {
415
    LOG(0, ("clipboard_send_data_response: error "
430
    LOG(0, ("clipboard_send_data_response: error "
416
        "clipboard_out_unicode didn't write right number of bytes"));
431
        "clipboard_out_unicode didn't write right number of bytes"));
432
    //DBGLOG("clipboard","clipboard_send_data_response: error (clipboard_out_unicode didn't write right number of bytes)");
417
  }
433
  }
418
  out_uint16_le(s, 0); /* nil for string */
434
  out_uint16_le(s, 0); /* nil for string */
419
  out_uint32_le(s, 0);
435
  out_uint32_le(s, 0);
420
  s_mark_end(s);
436
  s_mark_end(s);
421
  size = (int)(s->end - s->data);
437
  size = s->end - s->data;
422
  LOG(5, ("clipboard_send_data_response: data out, sending "
438
  LOG(5, ("clipboard_send_data_response: data out, sending "
423
      "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d",
439
      "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d",
424
      size, num_chars));
440
      size, num_chars));
 Lines 433-438    Link Here 
433
{
449
{
434
  Window owner;
450
  Window owner;
435
451
452
  g_memset(&owner,0,sizeof(Window));
453
454
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_set_selection_owner() called");
436
  g_selection_time = clipboard_get_server_time();
455
  g_selection_time = clipboard_get_server_time();
437
  XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time);
456
  XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time);
438
  owner = XGetSelectionOwner(g_display, g_clipboard_atom);
457
  owner = XGetSelectionOwner(g_display, g_clipboard_atom);
 Lines 447-457    Link Here 
447
466
448
/*****************************************************************************/
467
/*****************************************************************************/
449
static int APP_CC
468
static int APP_CC
450
clipboard_provide_selection(XSelectionRequestEvent* req, Atom type, int format,
469
clipboard_provide_selection(XSelectionRequestEvent * req, Atom type, int format,
451
                            char* data, int length)
470
                            char * data, size_t length)
452
{
471
{
453
  XEvent xev;
472
  XEvent xev;
454
473
474
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_provide_selection() called");
455
  XChangeProperty(g_display, req->requestor, req->property,
475
  XChangeProperty(g_display, req->requestor, req->property,
456
                  type, format, PropModeReplace, (tui8*)data, length);
476
                  type, format, PropModeReplace, (tui8*)data, length);
457
  g_memset(&xev, 0, sizeof(xev));
477
  g_memset(&xev, 0, sizeof(xev));
 Lines 473-478    Link Here 
473
{
493
{
474
  XEvent xev;
494
  XEvent xev;
475
495
496
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_refuse_selection() called");
476
  g_memset(&xev, 0, sizeof(xev));
497
  g_memset(&xev, 0, sizeof(xev));
477
  xev.xselection.type = SelectionNotify;
498
  xev.xselection.type = SelectionNotify;
478
  xev.xselection.send_event = True;
499
  xev.xselection.send_event = True;
 Lines 489-499    Link Here 
489
/*****************************************************************************/
510
/*****************************************************************************/
490
static int APP_CC
511
static int APP_CC
491
clipboard_process_format_announce(struct stream* s, int clip_msg_status,
512
clipboard_process_format_announce(struct stream* s, int clip_msg_status,
492
                                  int clip_msg_len)
513
                                  size_t clip_msg_len)
493
{
514
{
494
  Window owner;
515
  Window owner;
495
516
517
  g_memset(&owner,0,sizeof(Window));
518
496
  LOG(5, ("clipboard_process_format_announce: CLIPRDR_FORMAT_ANNOUNCE"));
519
  LOG(5, ("clipboard_process_format_announce: CLIPRDR_FORMAT_ANNOUNCE"));
520
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_process_format_announce(): CLIPRDR_FORMAT_ANNOUNCE");
497
  //g_hexdump(s->p, s->end - s->p);
521
  //g_hexdump(s->p, s->end - s->p);
498
  clipboard_send_format_ack();
522
  clipboard_send_format_ack();
499
  g_got_format_announce = 1;
523
  g_got_format_announce = 1;
 Lines 501-516    Link Here 
501
  if (clipboard_set_selection_owner() != 0)
525
  if (clipboard_set_selection_owner() != 0)
502
  {
526
  {
503
    LOG(0, ("clipboard_process_format_announce: XSetSelectionOwner failed"));
527
    LOG(0, ("clipboard_process_format_announce: XSetSelectionOwner failed"));
528
    //DBGLOG("clipboard","clipboard_process_format_announce: XSetSelectionOwner failed");
504
  }
529
  }
505
  return 0;
530
  return 0;
506
}
531
}
507
532
508
/*****************************************************************************/
533
/*****************************************************************************/
509
static int APP_CC
534
static int APP_CC
510
clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status,
535
clipboard_process_format_ack(struct stream* s, int clip_msg_status,
511
                             int clip_msg_len)
536
                             size_t clip_msg_len)
512
{
537
{
513
  LOG(5, ("clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK"));
538
  LOG(5, ("clipboard_process_format_ack: CLIPRDR_FORMAT_ACK"));
539
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_process_format_ack(): CLIPRDR_FORMAT_ACK");
514
  //g_hexdump(s->p, s->end - s->p);
540
  //g_hexdump(s->p, s->end - s->p);
515
  return 0;
541
  return 0;
516
}
542
}
 Lines 518-526    Link Here 
518
/*****************************************************************************/
544
/*****************************************************************************/
519
static int APP_CC
545
static int APP_CC
520
clipboard_process_data_request(struct stream* s, int clip_msg_status,
546
clipboard_process_data_request(struct stream* s, int clip_msg_status,
521
                               int clip_msg_len)
547
                               size_t clip_msg_len)
522
{
548
{
523
  LOG(5, ("clipboard_process_data_request: CLIPRDR_DATA_REQUEST"));
549
  LOG(5, ("clipboard_process_data_request: CLIPRDR_DATA_REQUEST"));
550
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_process_data_request(): CLIPRDR_DATA_REQUEST");
524
  //g_hexdump(s->p, s->end - s->p);
551
  //g_hexdump(s->p, s->end - s->p);
525
  clipboard_send_data_response();
552
  clipboard_send_data_response();
526
  return 0;
553
  return 0;
 Lines 529-548    Link Here 
529
/*****************************************************************************/
556
/*****************************************************************************/
530
static int APP_CC
557
static int APP_CC
531
clipboard_process_data_response(struct stream* s, int clip_msg_status,
558
clipboard_process_data_response(struct stream* s, int clip_msg_status,
532
                                int clip_msg_len)
559
                                size_t clip_msg_len)
533
{
560
{
534
  XEvent xev;
561
  XEvent xev;
535
  XSelectionRequestEvent* lxev;
562
  XSelectionRequestEvent * lxev = (XSelectionRequestEvent *)NULL;
536
  twchar* wtext;
563
  twchar * wtext = (twchar *)NULL;
537
  twchar wchr;
564
  twchar wchr;
538
  int len;
565
  ptrdiff_t len = 0;
539
  int index;
566
  ptrdiff_t index = 0;
540
  int wtext_size;
567
  ptrdiff_t wtext_size = 0;
541
  int data_in_len;
568
  ptrdiff_t data_in_len = 0;
569
570
  g_memset(&xev,0,sizeof(XEvent));
571
  g_memset(&wchr,0,sizeof(twchar));
542
572
543
  LOG(5, ("clipboard_process_data_response: CLIPRDR_DATA_RESPONSE"));
573
  LOG(5, ("clipboard_process_data_response: CLIPRDR_DATA_RESPONSE"));
574
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_process_data_response(): CLIPRDR_DATA_RESPONSE");
544
  g_waiting_for_data_response = 0;
575
  g_waiting_for_data_response = 0;
545
  len = (int)(s->end - s->p);
576
  len = s->end - s->p;
546
  if (len < 1)
577
  if (len < 1)
547
  {
578
  {
548
    return 0;
579
    return 0;
 Lines 565-571    Link Here 
565
    index++;
596
    index++;
566
  }
597
  }
567
  wtext[index] = 0;
598
  wtext[index] = 0;
568
  g_free(g_data_in);
599
  //g_free(g_data_in);
569
  g_data_in = 0;
600
  g_data_in = 0;
570
  g_data_in_size = 0;
601
  g_data_in_size = 0;
571
  g_data_in_time = 0;
602
  g_data_in_time = 0;
 Lines 575-585    Link Here 
575
    g_data_in = (char*)g_malloc(len + 16, 0);
606
    g_data_in = (char*)g_malloc(len + 16, 0);
576
    if (g_data_in == 0)
607
    if (g_data_in == 0)
577
    {
608
    {
578
      g_free(wtext);
609
      //g_free(wtext);
579
      return 0;
610
      return 0;
580
    }
611
    }
581
    g_data_in_size = len;
612
    g_data_in_size = len;
582
    g_wcstombs(g_data_in, wtext, len + 1);
613
    g_wcstombs(g_data_in, wtext, len + 1);
614
    len = g_strlen(g_data_in);
583
    g_data_in_time = clipboard_get_local_time();
615
    g_data_in_time = clipboard_get_local_time();
584
    g_data_in_up_to_date = 1;
616
    g_data_in_up_to_date = 1;
585
  }
617
  }
 Lines 596-616    Link Here 
596
    }
628
    }
597
  }
629
  }
598
  g_selection_request_event_count = 0;
630
  g_selection_request_event_count = 0;
599
  g_free(wtext);
631
  //g_free(wtext);
600
  return 0;
632
  return 0;
601
}
633
}
602
634
603
/*****************************************************************************/
635
/*****************************************************************************/
604
int APP_CC
636
int APP_CC
605
clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
637
clipboard_data_in(struct stream* s, int chan_id, int chan_flags, size_t length,
606
                  int total_length)
638
                  size_t total_length)
607
{
639
{
608
  int clip_msg_id;
640
  int rv = 0;
609
  int clip_msg_len;
641
  int clip_msg_id = 0;
610
  int clip_msg_status;
642
  ptrdiff_t clip_msg_len = 0;
611
  int rv;
643
  int clip_msg_status = 0;
612
  struct stream* ls;
644
  struct stream * ls = (struct stream *)NULL;
613
645
646
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_data_in() called");
614
  LOG(10, ("clipboard_data_in: chan_is %d "
647
  LOG(10, ("clipboard_data_in: chan_is %d "
615
      "chan_flags %d length %d total_length %d",
648
      "chan_flags %d length %d total_length %d",
616
      chan_id, chan_flags, length, total_length));
649
      chan_id, chan_flags, length, total_length));
 Lines 646-652    Link Here 
646
                                             clip_msg_len);
679
                                             clip_msg_len);
647
      break;
680
      break;
648
    case 3: /* CLIPRDR_FORMAT_ACK */
681
    case 3: /* CLIPRDR_FORMAT_ACK */
649
      rv = clipboard_prcoess_format_ack(ls, clip_msg_status,
682
      rv = clipboard_process_format_ack(ls, clip_msg_status,
650
                                        clip_msg_len);
683
                                        clip_msg_len);
651
      break;
684
      break;
652
    case 4: /* CLIPRDR_DATA_REQUEST */
685
    case 4: /* CLIPRDR_DATA_REQUEST */
 Lines 680-690    Link Here 
680
    Time timestamp;
713
    Time timestamp;
681
    Time selection_timestamp;
714
    Time selection_timestamp;
682
} XFixesSelectionNotifyEvent; */
715
} XFixesSelectionNotifyEvent; */
716
683
static int APP_CC
717
static int APP_CC
684
clipboard_event_selection_owner_notify(XEvent* xevent)
718
clipboard_event_selection_owner_notify(XEvent* xevent)
685
{
719
{
686
  XFixesSelectionNotifyEvent* lxevent;
720
  XFixesSelectionNotifyEvent * lxevent = (XFixesSelectionNotifyEvent *)NULL;
687
721
722
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_owner_notify() called");
688
  lxevent = (XFixesSelectionNotifyEvent*)xevent;
723
  lxevent = (XFixesSelectionNotifyEvent*)xevent;
689
  LOG(5, ("clipboard_event_selection_owner_notify: "
724
  LOG(5, ("clipboard_event_selection_owner_notify: "
690
      "window %d subtype %d owner %d g_wnd %d",
725
      "window %d subtype %d owner %d g_wnd %d",
 Lines 692-698    Link Here 
692
  if (lxevent->owner == g_wnd)
727
  if (lxevent->owner == g_wnd)
693
  {
728
  {
694
    LOG(5, ("clipboard_event_selection_owner_notify: skipping, "
729
    LOG(5, ("clipboard_event_selection_owner_notify: skipping, "
695
        "onwer == g_wnd"));
730
        "owner == g_wnd"));
696
    g_got_selection = 1;
731
    g_got_selection = 1;
697
    return 0;
732
    return 0;
698
  }
733
  }
 Lines 706-721    Link Here 
706
/* returns error
741
/* returns error
707
   get a window property from wnd */
742
   get a window property from wnd */
708
static int APP_CC
743
static int APP_CC
709
clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
744
clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int * fmt,
710
                              int* n_items, char** xdata, int* xdata_size)
745
                              size_t * n_items, char** xdata, size_t * xdata_size)
711
{
746
{
712
  int lfmt;
747
  int lfmt = 0;
713
  int lxdata_size;
748
  size_t lxdata_size = 0;
714
  unsigned long ln_items;
749
  unsigned long int ln_items = 0;
715
  unsigned long llen_after;
750
  unsigned long int llen_after = 0;
716
  tui8* lxdata;
751
  tui8 * lxdata = (tui8 *)NULL;
717
  Atom ltype;
752
  Atom ltype;
718
753
754
  g_memset(&ltype,0,sizeof(Atom));
755
756
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_window_property() called");
719
  lxdata = 0;
757
  lxdata = 0;
720
  ltype = 0;
758
  ltype = 0;
721
  XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0,
759
  XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0,
 Lines 725-735    Link Here 
725
  if (ltype == 0)
763
  if (ltype == 0)
726
  {
764
  {
727
    /* XGetWindowProperty failed */
765
    /* XGetWindowProperty failed */
766
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_window_property(): XGetWindowProperty() failed");
728
    return 1;
767
    return 1;
729
  }
768
  }
730
  if (llen_after < 1)
769
  if (llen_after < 1)
731
  {
770
  {
732
    /* no data, ok */
771
    /* no data, ok */
772
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_window_property(): no data, OK");
733
    return 0;
773
    return 0;
734
  }
774
  }
735
  lxdata = 0;
775
  lxdata = 0;
 Lines 740-745    Link Here 
740
  if (ltype == 0)
780
  if (ltype == 0)
741
  {
781
  {
742
    /* XGetWindowProperty failed */
782
    /* XGetWindowProperty failed */
783
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_window_property(): XGetWindowProperty() failed");
743
    XFree(lxdata);
784
    XFree(lxdata);
744
    return 1;
785
    return 1;
745
  }
786
  }
 Lines 747-758    Link Here 
747
  if (lxdata_size < 1)
788
  if (lxdata_size < 1)
748
  {
789
  {
749
    /* should not happen */
790
    /* should not happen */
791
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_window_property(): lxdata_size < 1!");
750
    XFree(lxdata);
792
    XFree(lxdata);
751
    return 2;
793
    return 2;
752
  }
794
  }
753
  if (llen_after > 0)
795
  if (llen_after > 0)
754
  {
796
  {
755
    /* should not happen */
797
    /* should not happen */
798
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_window_property(): ilen_after > 0!");
756
    XFree(lxdata);
799
    XFree(lxdata);
757
    return 3;
800
    return 3;
758
  }
801
  }
 Lines 778-783    Link Here 
778
  {
821
  {
779
    *type = ltype;
822
    *type = ltype;
780
  }
823
  }
824
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_window_property() done.");
781
  return 0;
825
  return 0;
782
}
826
}
783
827
 Lines 795-817    Link Here 
795
     Atom property;        // atom or None
839
     Atom property;        // atom or None
796
     Time time;
840
     Time time;
797
   } XSelectionEvent; */
841
   } XSelectionEvent; */
842
798
static int APP_CC
843
static int APP_CC
799
clipboard_event_selection_notify(XEvent* xevent)
844
clipboard_event_selection_notify(XEvent* xevent)
800
{
845
{
801
  XSelectionEvent* lxevent;
846
  XSelectionEvent * lxevent = (XSelectionEvent *)NULL;
802
  char* data;
847
  char * data = (char *)NULL;
803
  int data_size;
848
  size_t data_size = 0;
804
  int n_items;
849
  size_t n_items = 0;
805
  int fmt;
850
  int fmt = 0;
806
  int rv;
851
  int rv = 0;
807
  int index;
852
  ptrdiff_t index = 0;
808
  int convert_to_string;
853
  unsigned char convert_to_string = 0;
809
  int convert_to_utf8;
854
  unsigned char convert_to_utf8 = 0;
810
  int send_format_announce;
855
  unsigned char send_format_announce = 0;
811
  int atom;
856
  int atom = 0;
812
  int* atoms;
857
  int * atoms = (int *)NULL;
858
  //Atom *atoms;
813
  Atom type;
859
  Atom type;
860
  char tbuf[256] = "";
861
  char tbuf2[256] = "";
862
  char * tbuf3 = (char *)NULL;
863
  Status st;
814
864
865
  g_memset(&type,0,sizeof(Atom));
866
  g_memset(&st,0,sizeof(Status));
867
  g_memset(tbuf,0,sizeof(char) * 256);
868
  g_memset(tbuf2,0,sizeof(char) * 256);
869
870
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_notify() called");
815
  LOG(5, ("clipboard_event_selection_notify:"));
871
  LOG(5, ("clipboard_event_selection_notify:"));
816
  convert_to_string = 0;
872
  convert_to_string = 0;
817
  convert_to_utf8 = 0;
873
  convert_to_utf8 = 0;
 Lines 824-829    Link Here 
824
  {
880
  {
825
    LOG(0, ("clipboard_event_selection_notify: clip could "
881
    LOG(0, ("clipboard_event_selection_notify: clip could "
826
        "not be converted"));
882
        "not be converted"));
883
    MDBGLOG("clipboard","INFO\t[%s()]: clip could not be converted",__func__);
827
    rv = 1;
884
    rv = 1;
828
  }
885
  }
829
  if (rv == 0)
886
  if (rv == 0)
 Lines 835-840    Link Here 
835
    {
892
    {
836
      LOG(0, ("clipboard_event_selection_notify: "
893
      LOG(0, ("clipboard_event_selection_notify: "
837
          "clipboard_get_window_property failed error %d", rv));
894
          "clipboard_get_window_property failed error %d", rv));
895
      MDBGLOG("clipboard","ERROR\t[%s()]: clipboard_get_window_property() failed (error %d)", __func__, rv);
838
    }
896
    }
839
    XDeleteProperty(g_display, lxevent->requestor, lxevent->property);
897
    XDeleteProperty(g_display, lxevent->requestor, lxevent->property);
840
  }
898
  }
 Lines 846-857    Link Here 
846
      {
904
      {
847
        if ((type == XA_ATOM) && (fmt == 32))
905
        if ((type == XA_ATOM) && (fmt == 32))
848
        {
906
        {
849
          atoms = (int*)data;
907
          atoms = (int *)data;
850
          for (index = 0; index < n_items; index++)
908
          for (index = 0; index < n_items; index++)
851
          {
909
          {
852
            atom = atoms[index];
910
           atom = atoms[index];
853
            LOG(5, ("clipboard_event_selection_notify: %d %s %d", atom,
911
	   if (atom!=0) {
854
                XGetAtomName(g_display, atom), XA_STRING));
912
            //LOG(5, ("clipboard_event_selection_notify: %d %s %d", atom,
913
            //    XGetAtomName(g_display, atom), XA_STRING));
914
	    //snprintf(tbuf,255," (%d of %d) [xrdp-chansrv]->clipboard_event_selection_notify(): %d %s\0", index, n_items, atom, XGetAtomName(g_display, atom));
915
	    //tbuf3 = XGetAtomName(g_display, atom);
916
	    //snprintf(tbuf,255," (%d of %d) [xrdp-chansrv]->clipboard_event_selection_notify(): %d %s\0", index, n_items, atom, tbuf3);
917
	    ////DBGLOG("clipboard",tbuf);
855
            if (atom == g_utf8_atom)
918
            if (atom == g_utf8_atom)
856
            {
919
            {
857
              convert_to_utf8 = 1;
920
              convert_to_utf8 = 1;
 Lines 860-865    Link Here 
860
            {
923
            {
861
              convert_to_string = 1;
924
              convert_to_string = 1;
862
            }
925
            }
926
	   }
863
          }
927
          }
864
        }
928
        }
865
        else
929
        else
 Lines 873-879    Link Here 
873
      {
937
      {
874
        LOG(5, ("clipboard_event_selection_notify: UTF8_STRING data_size %d",
938
        LOG(5, ("clipboard_event_selection_notify: UTF8_STRING data_size %d",
875
            data_size));
939
            data_size));
876
        g_free(g_last_clip_data);
940
        MDBGLOG("clipboard","ERROR\t[%s()]: UTF8_STRING data_size = %d",__func__,data_size);
941
        //g_free(g_last_clip_data);
877
        g_last_clip_size = data_size;
942
        g_last_clip_size = data_size;
878
        g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
943
        g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
879
        g_last_clip_type = g_utf8_atom;
944
        g_last_clip_type = g_utf8_atom;
 Lines 885-891    Link Here 
885
      {
950
      {
886
        LOG(5, ("clipboard_event_selection_notify: XA_STRING data_size %d",
951
        LOG(5, ("clipboard_event_selection_notify: XA_STRING data_size %d",
887
            data_size));
952
            data_size));
888
        g_free(g_last_clip_data);
953
        //snprintf(tbuf,255,"[xrdp-chansrv]->clipboard_event_selection_notify(): XA_STRING data_size = %d",data_size);
954
	//DBGLOG("clipboard",tbuf);
955
        //g_free(g_last_clip_data);
889
        g_last_clip_size = data_size;
956
        g_last_clip_size = data_size;
890
        g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
957
        g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
891
        g_last_clip_type = XA_STRING;
958
        g_last_clip_type = XA_STRING;
 Lines 896-915    Link Here 
896
      else
963
      else
897
      {
964
      {
898
        LOG(0, ("clipboard_event_selection_notify: unknown target"));
965
        LOG(0, ("clipboard_event_selection_notify: unknown target"));
966
      //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_notify(): unknown target");
899
      }
967
      }
900
    }
968
    }
901
    else
969
    else
902
    {
970
    {
903
      LOG(0, ("clipboard_event_selection_notify: unknown selection"));
971
      LOG(0, ("clipboard_event_selection_notify: unknown selection"));
972
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_notify(): unknown selection");
904
    }
973
    }
905
  }
974
  }
906
  if (convert_to_utf8)
975
  if (convert_to_utf8)
907
  {
976
  {
977
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_notify(): convert_to_utf8");
908
    XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom,
978
    XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom,
909
                      g_clip_property_atom, g_wnd, lxevent->time);
979
                      g_clip_property_atom, g_wnd, lxevent->time);
910
  }
980
  }
911
  else if (convert_to_string)
981
  else if (convert_to_string)
912
  {
982
  {
983
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_notify(): convert_to_string");
913
    XConvertSelection(g_display, g_clipboard_atom, XA_STRING,
984
    XConvertSelection(g_display, g_clipboard_atom, XA_STRING,
914
                      g_clip_property_atom, g_wnd, lxevent->time);
985
                      g_clip_property_atom, g_wnd, lxevent->time);
915
  }
986
  }
 Lines 920-926    Link Here 
920
      rv = 4;
991
      rv = 4;
921
    }
992
    }
922
  }
993
  }
923
  g_free(data);
994
  //g_free(data);
924
  return rv;
995
  return rv;
925
}
996
}
926
997
 Lines 939-956    Link Here 
939
     Atom property;
1010
     Atom property;
940
     Time time;
1011
     Time time;
941
   } XSelectionRequestEvent; */
1012
   } XSelectionRequestEvent; */
1013
942
static int APP_CC
1014
static int APP_CC
943
clipboard_event_selection_request(XEvent* xevent)
1015
clipboard_event_selection_request(XEvent* xevent)
944
{
1016
{
945
  XEvent xev;
1017
  XEvent xev;
946
  XSelectionRequestEvent* lxev;
1018
  XSelectionRequestEvent* lxev = (XSelectionRequestEvent *)NULL;
947
  tui32 ui32[8];
1019
  tui32 ui32[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
948
  Atom type;
1020
  Atom type;
949
  int fmt;
1021
  int fmt = 0;
950
  int n_items;
1022
  size_t n_items = 0;
951
  int xdata_size;
1023
  size_t xdata_size = 0;
952
  char* xdata;
1024
  char* xdata = (char *)NULL;
1025
  char tbuf[256] = "";
1026
1027
  g_memset(tbuf,0,sizeof(char) * 256);
1028
  g_memset(&type,0,sizeof(Atom));
1029
  g_memset(&xev,0,sizeof(XEvent));
953
1030
1031
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_request() called");
954
  lxev = (XSelectionRequestEvent*)xevent;
1032
  lxev = (XSelectionRequestEvent*)xevent;
955
  LOG(5, ("clipboard_event_selection_request: g_wnd %d, "
1033
  LOG(5, ("clipboard_event_selection_request: g_wnd %d, "
956
      ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
1034
      ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
 Lines 960-970    Link Here 
960
  if (lxev->property == None)
1038
  if (lxev->property == None)
961
  {
1039
  {
962
    LOG(5, ("clipboard_event_selection_request: lxev->property is None"));
1040
    LOG(5, ("clipboard_event_selection_request: lxev->property is None"));
1041
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_request(): lxev->property is None");
963
  }
1042
  }
964
  else if (lxev->target == g_targets_atom)
1043
  else if (lxev->target == g_targets_atom)
965
  {
1044
  {
966
    /* requestor is asking what the selection can be converted to */
1045
    /* requestor is asking what the selection can be converted to */
967
    LOG(5, ("clipboard_event_selection_request: g_targets_atom"));
1046
    LOG(5, ("clipboard_event_selection_request: g_targets_atom"));
1047
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_request(): g_targets_atom");
968
    ui32[0] = g_targets_atom;
1048
    ui32[0] = g_targets_atom;
969
    ui32[1] = g_timestamp_atom;
1049
    ui32[1] = g_timestamp_atom;
970
    ui32[2] = g_multiple_atom;
1050
    ui32[2] = g_multiple_atom;
 Lines 976-998    Link Here 
976
  {
1056
  {
977
    /* requestor is asking the time I got the selection */
1057
    /* requestor is asking the time I got the selection */
978
    LOG(5, ("clipboard_event_selection_request: g_timestamp_atom"));
1058
    LOG(5, ("clipboard_event_selection_request: g_timestamp_atom"));
1059
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_request(): g_timestamp_atom");
979
    ui32[0] = g_selection_time;
1060
    ui32[0] = g_selection_time;
980
    return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)ui32, 1);
1061
    return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)ui32, 1);
981
  }
1062
  }
982
  else if (lxev->target == g_multiple_atom)
1063
  else if (lxev->target == g_multiple_atom)
983
  {
1064
  {
984
    /* target, property pairs */
1065
    /* target, property pairs */
985
    LOG(5, ("clipboard_event_selection_request: g_multiple_atom"));
1066
    LOG(5, ("[xrdp-chansrv]->clipboard_event_selection_request(): g_multiple_atom"));
986
    if (clipboard_get_window_property(xev.xselection.requestor,
1067
    //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_request(): g_multiple_atom");
987
                                      xev.xselection.property,
1068
//    if (clipboard_get_window_property(xev.xselection.requestor,
988
                                      &type, &fmt, &n_items, &xdata,
1069
//                                      xev.xselection.property,
989
                                      &xdata_size) == 0)
1070
//                                      &type, &fmt, &n_items, &xdata,
990
    {
1071
//                                      &xdata_size) == 0)
991
      LOG(5, ("clipboard_event_selection_request: g_multiple_atom "
1072
//    {
992
          "n_items %d", n_items));
1073
//      LOG(5, ("clipboard_event_selection_request: g_multiple_atom "
993
      /* todo */
1074
//          "n_items %d", n_items));
994
      g_free(xdata);
1075
//      /* todo */
995
    }
1076
//      //g_free(xdata);
1077
//    }
996
  }
1078
  }
997
  else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
1079
  else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
998
  {
1080
  {
 Lines 1006-1011    Link Here 
1006
    if (g_selection_request_event_count > 10)
1088
    if (g_selection_request_event_count > 10)
1007
    {
1089
    {
1008
      LOG(0, ("clipboard_event_selection_request: error, too many requests"));
1090
      LOG(0, ("clipboard_event_selection_request: error, too many requests"));
1091
      //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_request(): error, too many requests");
1009
    }
1092
    }
1010
    else
1093
    else
1011
    {
1094
    {
 Lines 1025-1030    Link Here 
1025
  {
1108
  {
1026
    LOG(0, ("clipboard_event_selection_request: unknown "
1109
    LOG(0, ("clipboard_event_selection_request: unknown "
1027
        "target %s", XGetAtomName(g_display, lxev->target)));
1110
        "target %s", XGetAtomName(g_display, lxev->target)));
1111
    snprintf(tbuf,255,"[xrdp-chansrv]->clipboard_event_selection_request(): unknown target (%s)\0", XGetAtomName(g_display, lxev->target));
1112
    //DBGLOG("clipboard",tbuf);
1028
  }
1113
  }
1029
  clipboard_refuse_selection(lxev);
1114
  clipboard_refuse_selection(lxev);
1030
  return 0;
1115
  return 0;
 Lines 1042-1050    Link Here 
1042
     Atom selection;
1127
     Atom selection;
1043
     Time time;
1128
     Time time;
1044
} XSelectionClearEvent; */
1129
} XSelectionClearEvent; */
1130
1045
static int APP_CC
1131
static int APP_CC
1046
clipboard_event_selection_clear(XEvent* xevent)
1132
clipboard_event_selection_clear(XEvent* xevent)
1047
{
1133
{
1134
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_selection_clear() called");
1048
  LOG(5, ("clipboard_event_selection_clear:"));
1135
  LOG(5, ("clipboard_event_selection_clear:"));
1049
  return 0;
1136
  return 0;
1050
}
1137
}
 Lines 1061-1069    Link Here 
1061
     Time time;
1148
     Time time;
1062
     int state;               // PropertyNewValue or PropertyDelete
1149
     int state;               // PropertyNewValue or PropertyDelete
1063
} XPropertyEvent; */
1150
} XPropertyEvent; */
1151
1064
static int APP_CC
1152
static int APP_CC
1065
clipboard_event_property_notify(XEvent* xevent)
1153
clipboard_event_property_notify(XEvent* xevent)
1066
{
1154
{
1155
  //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_event_property_notify() called");
1067
  LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d "
1156
  LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d "
1068
      ".state %d .atom %d", xevent->xproperty.window,
1157
      ".state %d .atom %d", xevent->xproperty.window,
1069
      xevent->xproperty.state, xevent->xproperty.atom));
1158
      xevent->xproperty.state, xevent->xproperty.atom));
 Lines 1075-1084    Link Here 
1075
   this is called to get any wait objects for the main loop
1164
   this is called to get any wait objects for the main loop
1076
   timeout can be nil */
1165
   timeout can be nil */
1077
int APP_CC
1166
int APP_CC
1078
clipboard_get_wait_objs(tbus* objs, int* count, int* timeout)
1167
clipboard_get_wait_objs(tbus* objs, ptrdiff_t * count, int * timeout)
1079
{
1168
{
1080
  int lcount;
1169
  ptrdiff_t lcount = 0;
1081
1170
1171
  ////DBGLOG("clipboard","[xrdp-chansrv]->clipboard_get_wait_objs() called");
1082
  if ((!g_clip_up) || (objs == 0) || (count == 0))
1172
  if ((!g_clip_up) || (objs == 0) || (count == 0))
1083
  {
1173
  {
1084
    return 0;
1174
    return 0;
 Lines 1095-1102    Link Here 
1095
clipboard_check_wait_objs(void)
1185
clipboard_check_wait_objs(void)
1096
{
1186
{
1097
  XEvent xevent;
1187
  XEvent xevent;
1098
  int time_diff;
1188
  int time_diff = 0;
1099
1189
1190
  ////DBGLOG("clipboard","[xrdp-chansrv]->clipboard_check_wait_objs() called");
1100
  if (!g_clip_up)
1191
  if (!g_clip_up)
1101
  {
1192
  {
1102
    return 0;
1193
    return 0;
 Lines 1107-1112    Link Here 
1107
    {
1198
    {
1108
      /* something is wrong, should not get here */
1199
      /* something is wrong, should not get here */
1109
      LOG(0, ("clipboard_check_wait_objs: sck closed"));
1200
      LOG(0, ("clipboard_check_wait_objs: sck closed"));
1201
      //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_check_wait_objs(): sck closed");
1110
      return 0;
1202
      return 0;
1111
    }
1203
    }
1112
    if (g_waiting_for_data_response)
1204
    if (g_waiting_for_data_response)
 Lines 1117-1122    Link Here 
1117
      {
1209
      {
1118
        LOG(0, ("clipboard_check_wait_objs: warning, waiting for "
1210
        LOG(0, ("clipboard_check_wait_objs: warning, waiting for "
1119
            "data response too long"));
1211
            "data response too long"));
1212
        //DBGLOG("clipboard","[xrdp-chansrv]->clipboard_check_wait_objs(): warning, waiting for data response too long");
1120
      }
1213
      }
1121
    }
1214
    }
1122
    while (XPending(g_display) > 0)
1215
    while (XPending(g_display) > 0)
 Lines 1147-1152    Link Here 
1147
          }
1240
          }
1148
          LOG(0, ("clipboard_check_wait_objs unknown type %d",
1241
          LOG(0, ("clipboard_check_wait_objs unknown type %d",
1149
              xevent.type));
1242
              xevent.type));
1243
          //MDBGLOG("clip","[xrdp-chansrv]->clipboard_check_wait_objs(): unknown type (%d)",xevent.type);
1150
          break;
1244
          break;
1151
      }
1245
      }
1152
    }
1246
    }
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/clipboard.h (-3 / +16 lines)
 Lines 2-19    Link Here 
2
#if !defined(CLIPBOARD_H)
2
#if !defined(CLIPBOARD_H)
3
#define CLIPBOARD_H
3
#define CLIPBOARD_H
4
4
5
#include <stddef.h>
6
#include <stdint.h>
7
5
#include "arch.h"
8
#include "arch.h"
6
#include "parse.h"
9
#include "parse.h"
7
10
11
#ifndef BYTE
12
#define BYTE uint8_t
13
#endif
14
#ifndef WORD
15
#define WORD uint16_t
16
#endif
17
#ifndef DWORD
18
#define DWORD uint32_t
19
#endif
20
8
int APP_CC
21
int APP_CC
9
clipboard_init(void);
22
clipboard_init(void);
10
int APP_CC
23
int APP_CC
11
clipboard_deinit(void);
24
clipboard_deinit(void);
12
int APP_CC
25
int APP_CC
13
clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
26
clipboard_data_in(struct stream* s, int chan_id, int chan_flags, size_t length,
14
                  int total_length);
27
	size_t total_length);
15
int APP_CC
28
int APP_CC
16
clipboard_get_wait_objs(tbus* objs, int* count, int* timeout);
29
clipboard_get_wait_objs(tbus* objs, ptrdiff_t * count, int* timeout);
17
int APP_CC
30
int APP_CC
18
clipboard_check_wait_objs(void);
31
clipboard_check_wait_objs(void);
19
32
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/devredir.c (-17 / +4438 lines)
 Lines 17-60    Link Here 
17
   Copyright (C) Jay Sorg 2009
17
   Copyright (C) Jay Sorg 2009
18
*/
18
*/
19
19
20
#include <pthread.h>
21
#include <stdint.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
20
#include "arch.h"
26
#include "arch.h"
21
#include "parse.h"
27
#include "chansrv.h"
28
#include "defines.h"
29
#include "devredir_defs.h"
30
#include "devredir.h"
22
#include "os_calls.h"
31
#include "os_calls.h"
32
#include "parse.h"
33
#include "rdpdr.h"
34
#include "rdpdr_methods.h"
35
#include "trans.h"
36
#include "thread_calls.h"
37
#include "thread_macros.h"
38
39
#include "dbg.h"
40
41
#if defined(MDBGLOG)
42
//#undef MDBGLOG
43
//#define MDBGLOG(...)	;
44
#endif
45
46
#ifndef MAX_PENDING
47
#define MAX_PENDING 512
48
#endif
49
50
#ifndef WO_PATH
51
#define WO_PATH		"/tmp/xrdp_chansrv_%8.8x_rdpdr"
52
#endif
53
54
#ifndef FSBASE_PATH
55
#define FSBASE_PATH	"/media/tsclient"
56
#endif
57
58
extern tc_t	g_out_mutex;
59
extern tc_p	mutex_out;
60
tc_p		mutex_client_devicelist = (tc_p)NULL;
61
static tc_t	g_client_devicelist_mutex;
62
static tc_t	g_fs_arr_mutex;
63
static tc_t	g_port_arr_mutex;
64
static tc_t	g_printer_arr_mutex;
65
static tc_t	g_smartcard_arr_mutex;
66
static tc_p	mutex_fs_arr = (tc_p)NULL;
67
static tc_p	mutex_port_arr = (tc_p)NULL;
68
static tc_p	mutex_printer_arr = (tc_p)NULL;
69
static tc_p	mutex_smartcard_arr = (tc_p)NULL;
70
71
static tc_t	g_cb_mutex;
72
static tc_p	mutex_cb = (tc_p)NULL;
73
74
DR_DEVICELIST_ANNOUNCE *	g_client_devicelist = NULL;
75
static char g_fbase[1024] = FSBASE_PATH;
76
77
static unsigned char	g_is_child			= 0;
78
static int		g_idx				= 0;
79
static int		g_handle_filesystem_called	= 0;
80
static tc_t		g_handle_filesystem_mutex;
81
static tc_p		g_handle_fs_mut = (tc_p)NULL;
82
83
static int		g_rdpdr_up			= 0;
84
static tbus		g_rdpdr_wait_obj		= -1;
85
static unsigned int	g_received_close_pdu		= 0;
86
static struct stream *	g_ins				= (struct stream *)NULL;
87
static int		g_client_announce_reply_received = 0;
88
static int		g_client_name_request_received	= 0;
89
static int		g_user_loggedon_sent		= 0;
90
static int		g_core_capabilities_requested	= 0;
91
static int		g_client_id			= 0x0001;
92
static char *		g_client_computer_name		= (char *)NULL;
93
static int		g_child_pid			= 0;
94
static int		l_child_pid			= 0;
95
static int		p_child_pid			= 0;
96
static int		s_child_pid			= 0;
97
static rdpfs **		g_fs_arr			= (rdpfs **)NULL;
98
static rdpport_t **	g_port_arr			= (rdpport_t **)NULL;
99
static rdpprint **	g_printer_arr			= (rdpprint **)NULL;
100
static rdpsc **		g_smartcard_arr			= (rdpsc **)NULL;
101
102
int		g_fs_count			= 0;
103
int		g_port_count			= 0;
104
int		g_printer_count			= 0;
105
int		g_smartcard_count		= 0;
106
107
static int		g_opid				= 5;
108
static callback		g_callbacks[MAX_PENDING];
109
static int		g_file_id			= -1;
110
111
static int					g_pending_operations[MAX_PENDING];
112
113
static int APP_CC rdpdr_process_format_announce(struct stream *, int, int);
114
static int APP_CC rdpdr_process_format_ack(struct stream *, int, int);
115
static int APP_CC rdpdr_process_data_request(struct stream *, int, int);
116
static int APP_CC rdpdr_process_data_response(struct stream *, int, int);
117
static int APP_CC rdpdr_process_DEVICELIST_ANNOUNCE(struct stream *);
118
119
static char * APP_CC ucs2ascii(const uint8_t *);
120
121
static int APP_CC rdpdr_child_loop(int);
122
static int APP_CC get_opid(void *);
123
static int APP_CC register_opid(void *, int);
124
static int APP_CC strike_opid(void *, int);
125
static int APP_CC opid_is_registered(void *, int);
126
static int APP_CC cb_set_data(struct _callback *, int, const BYTE *);
127
static int APP_CC cb_set_func(struct _callback *, void (*)(struct _rdpfs *, int, tbus, struct trans *, DWORD, DWORD, int, BYTE *));
128
static void * APP_CC cb_call(void *);
129
static int APP_CC cb_call_data(struct _callback *, int, const BYTE *);
130
static int APP_CC get_opcode_from_opid(int);
131
static callback * APP_CC get_callback_from_opid(int);
132
static void APP_CC cb_send_buf(struct _rdpfs *, int, tbus, struct trans *, DWORD, DWORD, int, BYTE *);
133
static void APP_CC cb_send_bare(struct _rdpfs *, int, tbus, struct trans *, DWORD, DWORD, int, BYTE *);
134
static inline int APP_CC is_filesystem(int);
135
static inline int APP_CC is_port(int);
136
static inline int APP_CC is_serial(int);
137
static inline int APP_CC is_parallel(int);
138
static inline int APP_CC is_printer(int);
139
static inline int APP_CC is_smartcard(int);
140
static int APP_CC get_device_index(int);
141
142
static int APP_CC rdpdr_process_DEVICE_REPLY(struct stream *);
143
static int APP_CC rdpdr_process_DEVICE_IOREQUEST(struct stream *);
144
static int APP_CC rdpdr_process_DEVICE_IOCOMPLETION(struct stream *);
145
static int APP_CC rdpdr_process_SERVER_CAPABILITY(struct stream *);
146
static int APP_CC rdpdr_process_CLIENT_CAPABILITY(struct stream *);
147
static int APP_CC rdpdr_process_DEVICELIST_REMOVE(struct stream *);
148
149
char * APP_CC ntstatus_string(uint32_t);
150
static int APP_CC filesystem_data_in(struct trans *);
151
static int APP_CC port_data_in(struct trans *);
152
static int APP_CC printer_data_in(struct trans *);
153
static int APP_CC smartcard_data_in(struct trans *);
154
155
static void test_serial_port(int);
156
157
158
static tc_t g_getattr_mutex;
159
static tc_p mutex_getattr = (tc_p)NULL;
160
struct getattr_queue;
161
typedef struct getattr_queue {
162
  struct getattr_queue *		next;
163
  struct getattr_queue *		prev;
164
  int					device_id;
165
  int					basic_done;
166
  int					fhandle;
167
  int					uniqid;
168
  int					opid;
169
  int					opcode;
170
  tc_t					lock;
171
  DR_DRIVE_QUERY_INFORMATION_RSP	rsp;
172
} getattr_queue_t, * getattr_queue_p;
173
static getattr_queue_t * g_getattr_q = (getattr_queue_t *)NULL;
174
175
#define GETATTR_CREATE()	(getattr_queue_t *)g_malloc(sizeof(getattr_queue_t), 1)
176
#define GETATTR_INIT(x)			{				\
177
  if (x != NULL) {							\
178
    tc_t	l_tattr;						\
179
    tc_p	p_tattr = (tc_p)(&l_tattr);				\
180
    g_memset((void *)(&l_tattr),0,sizeof(tc_t));			\
181
    TC_MUTATTR_INIT((tc_p)p_tattr);					\
182
    TC_MUTEX_INIT((tc_p)(&(x->lock)), (tc_p)p_tattr);			\
183
  }									\
184
}
185
#define DECLARE_GETATTR(inx)						\
186
  getattr_queue_t * inx = (getattr_queue_t *)NULL;			\
187
  {									\
188
    inx = GETATTR_CREATE();						\
189
    if (inx != NULL) {							\
190
       GETATTR_INIT(inx);						\
191
    }									\
192
  }									
193
#define GETATTR_ENQ(x)			{ 				\
194
  if (g_getattr_q == NULL) {						\
195
    g_getattr_q = x;							\
196
    if (g_getattr_q != NULL) {						\
197
      g_getattr_q->prev = NULL;						\
198
      g_getattr_q->next = NULL;						\
199
    }									\
200
  }									\
201
  else {								\
202
    getattr_queue_t * tlmp = (getattr_queue_t *)NULL;			\
203
    tlmp = g_getattr_q;							\
204
    while (tlmp != NULL && tlmp->next != NULL) {			\
205
      tlmp = tlmp->next;						\
206
    }									\
207
    tlmp->next = x;							\
208
    if (x != NULL) {							\
209
      x->prev = tlmp;							\
210
      x->next = NULL;							\
211
    }									\
212
  }									\
213
}
214
#define GETATTR_DEQ(x)			{				\
215
  if (x != NULL) {							\
216
    (*(x)) = g_getattr_q;						\
217
    (*(x))->prev = NULL;						\
218
    (*(x))->next = NULL;						\
219
  }									\
220
  if (g_getattr_q != NULL) {						\
221
    g_getattr_q = g_getattr_q->next;					\
222
    g_getattr_q->prev = NULL;						\
223
  }									\
224
}
225
#define GETATTR_FIND(x, y, z)		{				\
226
    if (g_getattr_q == NULL) {						\
227
      z = NULL;								\
228
    }									\
229
    else {								\
230
      int tdone = 0;							\
231
      getattr_queue_t * tlmp = (getattr_queue_t *)NULL;			\
232
      z = tlmp;								\
233
      tlmp = g_getattr_q;						\
234
      if (tlmp != NULL && tlmp->device_id == x && tlmp->opid == y) {	\
235
	z = tlmp;							\
236
	tdone = 1;							\
237
      }									\
238
      while (tlmp != NULL && tdone < 1) {				\
239
	if (tlmp->device_id == x && tlmp->opid == y) {			\
240
	  z = tlmp;							\
241
	  tdone = 1;							\
242
	}								\
243
	else {								\
244
	  tlmp = tlmp->next;						\
245
	}								\
246
      }									\
247
    }									\
248
}
249
#define GETATTR_CUT(x)	{						\
250
    if (x != NULL) {							\
251
      if (x->prev == NULL) {						\
252
	g_getattr_q = g_getattr_q->next;				\
253
	if (g_getattr_q != NULL) {					\
254
	  g_getattr_q->prev = NULL;					\
255
	}								\
256
      }									\
257
      else if (x->prev != NULL) {					\
258
	x->prev->next = x->next;					\
259
	if (x->next != NULL) {						\
260
	  x->next->prev = x->prev;					\
261
	}								\
262
      }									\
263
    }									\
264
}
265
266
static int g_no_more_files = 0;
267
static struct stream * g_u = (struct stream *)NULL;
268
269
tc_mut_t g_mutex;
270
tc_p mut = (tc_p)NULL;
271
272
extern int g_rdpdr_chan_id;				/* in chansrv.c */
273
extern rdpfs * rdpfs_main(int, char **, char *);	/* in rdpfs.c */
274
extern int handle_filesystem(tbus, rdpfs *, rdpfs **, tc_p);		/* in rdpfs.c */
275
extern rdpport_t * rdpport_main(int, int);		/* in rdpport.c */
276
extern int handle_port(tbus, rdpport_t *);		/* in rdpport.c */
277
extern void * rdpuart_addport(void *);			/* " 		*/
278
extern rdpprint * rdpprint_main(void);			/* in rdpprint.c */
279
extern int handle_printer(tbus, rdpprint *);		/* in rdpprint.c */
280
extern rdpsc * rdpsc_main(void);			/* in rdpsc.c */
281
extern int handle_smartcard(tbus, rdpsc *);		/* in rdpsc.c */
23
282
24
extern int g_rdpdr_chan_id; /* in chansrv.c */
25
283
26
/*****************************************************************************/
284
/*****************************************************************************/
27
int APP_CC
285
int APP_CC
28
dev_redir_init(void)
286
rdpdr_init(void) {
29
{
287
  struct stream * s = (struct stream *)NULL;
30
  return 0;
288
  int size = 0;
289
  int rv = 0;
290
  int pid = 0;
291
  int input_mask = 0;
292
  int dummy = 0;
293
  int ver_maj = 0;
294
  int ver_min = 0;
295
  char wo_fpath[512];
296
  void * pdu = (void *)NULL;
297
298
  MDBGLOG("redir","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
299
300
  mut = (tc_p)&g_mutex;
301
  tc_mutex_init(mut,NULL);
302
303
  g_no_more_files = 0;
304
  make_stream(g_u);
305
  init_stream(g_u, MAX_STREAM);
306
307
  {
308
    tc_t mattr;
309
    tc_p pattr = &mattr;
310
    tc_t nattr;
311
    tc_p pnattr = &nattr;
312
    TC_MUTATTR_INIT(pattr);
313
    TC_MUTATTR_SETTYPE(pattr, TC_MUTEX_ERRORCHECK);
314
    TC_MUTATTR_SETPSHARED(pattr, TC_PROCESS_SHARED);
315
    TC_MUTATTR_INIT(pnattr);
316
    TC_MUTATTR_SETTYPE(pnattr, TC_MUTEX_ERRORCHECK);
317
    TC_MUTATTR_SETPSHARED(pattr, TC_PROCESS_PRIVATE);
318
    g_handle_fs_mut = &g_handle_filesystem_mutex;
319
    TC_MUTEX_INIT(g_handle_fs_mut,pnattr);
320
    mutex_client_devicelist = &g_client_devicelist_mutex;
321
    TC_MUTEX_INIT(mutex_client_devicelist, pnattr);
322
    mutex_fs_arr = &g_fs_arr_mutex;
323
    TC_MUTEX_INIT(mutex_fs_arr, pnattr);
324
    mutex_port_arr = &g_port_arr_mutex;
325
    TC_MUTEX_INIT(mutex_port_arr, pnattr);
326
    mutex_printer_arr = &g_printer_arr_mutex;
327
    TC_MUTEX_INIT(mutex_printer_arr, pnattr);
328
    mutex_smartcard_arr = &g_smartcard_arr_mutex;
329
    TC_MUTEX_INIT(mutex_smartcard_arr, pnattr);
330
    mutex_cb = &g_cb_mutex;
331
    TC_MUTEX_INIT(mutex_cb, pnattr);
332
    mutex_getattr = &g_getattr_mutex;
333
    TC_MUTEX_INIT(mutex_getattr, pnattr);
334
  }
335
336
  g_memset(wo_fpath,0,sizeof(char) * 512);
337
  TC_MUTEX_LOCK(mutex_cb);
338
  g_memset((callback *)g_callbacks,0,sizeof(callback) * MAX_PENDING);
339
  TC_MUTEX_UNLOCK(mutex_cb);
340
341
  if (g_rdpdr_up)
342
  {
343
    return 0;
344
  }
345
  rdpdr_deinit();
346
347
  rv = 0;
348
  if (rv == 0)
349
  {
350
    /* Ascertain the PID of this process, for incorporating into the filename */
351
    pid = g_getpid();
352
353
    /* Construct path and filename for the wait object */
354
    g_snprintf(wo_fpath,511,WO_PATH,pid);
355
356
    /* Create wait object */
357
    g_rdpdr_wait_obj = g_create_wait_obj(wo_fpath);
358
  }
359
  if (rv == 0)
360
  {
361
    make_stream(s);
362
    init_stream(s, MAX_STREAM);
363
	/* First, output a DR_CORE_SERVER_ANNOUNCE_REQ: */
364
    pdu = RDPDR_NEW(DR_CORE_SERVER_ANNOUNCE_REQ);
365
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)pdu)->ClientId = 0x00000001;
366
    ((DR_CORE_SERVER_ANNOUNCE_REQ *)pdu)->out((DR_CORE_SERVER_ANNOUNCE_REQ *)pdu, s);
367
    s_mark_end(s);
368
    size = (int)(s->end - s->data);
369
    LOG(5, ("[xrdp-chansrv]->rdpdr_init(): data out, sending "
370
        "RDPDR_CONNECT (redir_msg_id = 1)"));
371
    MDBGLOG("redir","INFO\t[%s()]: data out, sending (redir_msg_id = 1)",__func__);
372
    TC_MUTEX_LOCK(mutex_out);
373
    rv = send_channel_data(g_rdpdr_chan_id, s->data, size);
374
    TC_MUTEX_UNLOCK(mutex_out);
375
    //LOG(5,("[xrdp-chansrv]->rdpdr_init(): g_rdpdr_chan_id = %d",g_rdpdr_chan_id));
376
    MDBGLOG("redir","INFO\t[%s()]: g_rdpdr_chan_id = %d",__func__,g_rdpdr_chan_id);
377
    if (rv != 0)
378
    {
379
      LOG(0, ("[xrdp-chansrv]->rdpdr_init(): send_channel_data failed "
380
          "rv = %d", rv));
381
      MDBGLOG("redir","INFO\t[%s()]: send_channel_data failed "
382
          "rv = %d", __func__, rv);
383
      rv = 4;
384
    }
385
    //free_stream(s);
386
  }
387
  if (rv == 0)
388
  {
389
    g_rdpdr_up = 1;
390
    make_stream(g_ins);
391
    init_stream(g_ins, MAX_STREAM)
392
  }
393
  else
394
  {
395
    LOG(0, ("xrdp-chansrv: rdpdr_init: error on exit"));
396
    MDBGLOG("redir","ERROR\t[%s()]: error on exit",__func__);
397
  }
398
  return rv;
31
}
399
}
32
400
33
/*****************************************************************************/
401
/*****************************************************************************/
34
int APP_CC
402
int APP_CC
35
dev_redir_deinit(void)
403
rdpdr_deinit(void) {
36
{
404
  int idx = 0;
405
406
  MDBGLOG("redir","INFO\t[%s()]: called",__func__);
407
408
  if (g_rdpdr_wait_obj > -1) {
409
    g_delete_wait_obj(g_rdpdr_wait_obj);
410
  }
411
412
  g_rdpdr_up			= 0;
413
  g_rdpdr_wait_obj		= -1;
414
  g_received_close_pdu		= 0;
415
  g_client_announce_reply_received = 0;
416
  g_client_name_request_received = 0;
417
  g_user_loggedon_sent		= 0;
418
  g_client_id			= 0x0001;
419
420
  if (g_client_computer_name != NULL) {
421
    //g_free(g_client_computer_name);
422
    g_client_computer_name = (char *)NULL;
423
  }
424
425
  if (g_ins != NULL) {
426
    //free_stream(g_ins);
427
    g_ins = (struct stream *)NULL;
428
  }
429
430
  TC_MUTEX_LOCK(mutex_fs_arr);
431
  if (g_fs_arr != NULL && g_fs_count > 0) {
432
    for (idx = 0; idx < g_fs_count; idx++) {
433
      if (g_fs_arr[idx] != NULL && g_fs_arr[idx]->mountpoint != NULL && g_strlen(g_fs_arr[idx]->mountpoint) > 0) {
434
	fuse_unmount(g_fs_arr[idx]->mountpoint, g_fs_arr[idx]->ch);
435
      }
436
    }
437
  }
438
  if (g_fs_arr != NULL && g_fs_count > 0) {
439
    for (idx = 0; idx < g_fs_count; idx++) {
440
      if (g_fs_arr[idx] != NULL) {
441
	if (g_fs_arr[idx]->child_pid > 0) {
442
	  g_waitpid(g_fs_arr[idx]->child_pid);
443
	}
444
	g_fs_arr[idx]->g_fs = NULL;
445
	if (g_fs_arr[idx]->ccon != NULL) {
446
	  //trans_delete(g_fs_arr[idx]->ccon);
447
	  g_free(g_fs_arr[idx]->ccon);
448
	  g_fs_arr[idx]->ccon = NULL;
449
	}
450
	if (g_fs_arr[idx]->mountpoint != NULL) {
451
	  g_free(g_fs_arr[idx]->mountpoint);
452
	  g_fs_arr[idx]->mountpoint = NULL;
453
	}
454
	if (g_fs_arr[idx]->dos_name != NULL) {
455
	  g_free(g_fs_arr[idx]->dos_name);
456
	  g_fs_arr[idx]->dos_name = NULL;
457
	}
458
	if (g_fs_arr[idx]->fuse != NULL) {
459
	  g_free(g_fs_arr[idx]->fuse);
460
	  g_fs_arr[idx]->fuse = NULL;
461
	}
462
	if (g_fs_arr[idx]->ch != NULL) {
463
	  g_free(g_fs_arr[idx]->ch);
464
	  g_fs_arr[idx]->ch = NULL;
465
	}
466
	if (g_fs_arr[idx]->host != NULL) {
467
	  g_free(g_fs_arr[idx]->host);
468
	  g_fs_arr[idx]->host = NULL;
469
	}
470
	if (g_fs_arr[idx]->base_path != NULL) {
471
	  g_free(g_fs_arr[idx]->base_path);
472
	  g_fs_arr[idx]->base_path = NULL;
473
	}
474
	if (g_fs_arr[idx]->progname != NULL) {
475
	  g_free(g_fs_arr[idx]->progname);
476
	  g_fs_arr[idx]->progname = NULL;
477
	}
478
	g_free(g_fs_arr[idx]);
479
      }
480
    }
481
  }
482
  TC_MUTEX_UNLOCK(mutex_fs_arr);
483
484
  TC_MUTEX_LOCK(mutex_port_arr);
485
  if (g_port_arr != NULL && g_port_count > 0) {
486
    for (idx = 0; idx < g_port_count; idx++) {
487
      if (g_port_arr[idx] != NULL) {
488
	if (g_port_arr[idx]->child_pid > 0) {
489
	  g_waitpid(g_port_arr[idx]->child_pid);
490
	}
491
	g_port_arr[idx]->g_port = NULL;
492
	if (g_port_arr[idx]->ccon != NULL) {
493
	  //trans_delete(g_port_arr[idx]->ccon);
494
	  g_free(g_port_arr[idx]->ccon);
495
	  g_port_arr[idx]->ccon = NULL;
496
	}
497
	if (g_port_arr[idx]->file_path != NULL) {
498
	  g_free(g_port_arr[idx]->file_path);
499
	  g_port_arr[idx]->file_path = NULL;
500
	}
501
	if (g_port_arr[idx]->dos_name != NULL) {
502
	  g_free(g_port_arr[idx]->dos_name);
503
	  g_port_arr[idx]->dos_name = NULL;
504
	}
505
	g_free(g_port_arr[idx]);
506
      }
507
    }
508
  }
509
  TC_MUTEX_UNLOCK(mutex_port_arr);
510
511
  TC_MUTEX_LOCK(mutex_printer_arr);
512
  if (g_printer_arr != NULL && g_printer_count > 0) {
513
    for (idx = 0; idx < g_printer_count; idx++) {
514
      if (g_printer_arr[idx] != NULL) {
515
	if (g_printer_arr[idx]->child_pid > 0) {
516
	  g_waitpid(g_printer_arr[idx]->child_pid);
517
	}
518
	g_printer_arr[idx]->g_printer = NULL;
519
	if (g_printer_arr[idx]->ccon != NULL) {
520
	  //trans_delete(g_printer_arr[idx]->ccon);
521
	  g_free(g_printer_arr[idx]->ccon);
522
	  g_printer_arr[idx]->ccon = NULL;
523
	}
524
	if (g_printer_arr[idx]->file_path != NULL) {
525
	  g_free(g_printer_arr[idx]->file_path);
526
	  g_printer_arr[idx]->file_path = NULL;
527
	}
528
	if (g_printer_arr[idx]->dos_name != NULL) {
529
	  g_free(g_printer_arr[idx]->dos_name);
530
	  g_printer_arr[idx]->dos_name = NULL;
531
	}
532
	g_free(g_printer_arr[idx]);
533
      }
534
    }
535
  }
536
  TC_MUTEX_UNLOCK(mutex_printer_arr);
537
538
  TC_MUTEX_LOCK(mutex_smartcard_arr);
539
  if (g_smartcard_arr != NULL && g_smartcard_count > 0) {
540
    for (idx = 0; idx < g_smartcard_count; idx++) {
541
      if (g_smartcard_arr[idx] != NULL) {
542
	if (g_smartcard_arr[idx]->child_pid > 0) {
543
	  g_waitpid(g_smartcard_arr[idx]->child_pid);
544
	}
545
	g_smartcard_arr[idx]->g_sc = NULL;
546
	if (g_smartcard_arr[idx]->ccon != NULL) {
547
	  //trans_delete(g_smartcard_arr[idx]->ccon);
548
	  g_free(g_smartcard_arr[idx]->ccon);
549
	  g_smartcard_arr[idx]->ccon = NULL;
550
	}
551
	if (g_smartcard_arr[idx]->file_path != NULL) {
552
	  g_free(g_smartcard_arr[idx]->file_path);
553
	  g_smartcard_arr[idx]->file_path = NULL;
554
	}
555
	if (g_smartcard_arr[idx]->dos_name != NULL) {
556
	  g_free(g_smartcard_arr[idx]->dos_name);
557
	  g_smartcard_arr[idx]->dos_name = NULL;
558
	}
559
	g_free(g_smartcard_arr[idx]);
560
      }
561
    }
562
  }
563
  TC_MUTEX_UNLOCK(mutex_smartcard_arr);
564
37
  return 0;
565
  return 0;
38
}
566
}
39
567
40
/*****************************************************************************/
568
/*****************************************************************************/
41
int APP_CC
569
int APP_CC
42
dev_redir_data_in(struct stream* s, int chan_id, int chan_flags, int length,
570
rdpdr_data_in(struct stream * s, int chan_id, int chan_flags, int length, int total_length) {
43
                  int total_length)
571
  int rdpdr_msg_id = 0;
44
{
572
  int rdpdr_msg_len = 0;
45
  return 0;
573
  int rdpdr_msg_status = 0;
574
  int rv = 0;
575
  int idx = 0;
576
  int size = 0;
577
  int rdp_opcode = 0;
578
  int send_partial = 0;
579
  struct stream * ls = (struct stream *)NULL;
580
  struct stream * ts = (struct stream *)NULL;
581
  struct stream * vs = (struct stream *)NULL;
582
  char * p = (char *)NULL;
583
  int devidx = 0;
584
  int fault = 0;
585
  int suppress = 0;
586
  int fhandle = 0;
587
  int uniqid = 0;
588
  uint32_t crc32 = 0x00000000;
589
  uint32_t magic = 0x00000000;
590
  uint32_t device_id = 0x00000000;
591
  BYTE buf[MAX_STREAM];
592
  DR_CORE_SERVER_ANNOUNCE_RSP * creply = (DR_CORE_SERVER_ANNOUNCE_RSP *)NULL;
593
  DR_CORE_CLIENT_NAME_REQ * cname = (DR_CORE_CLIENT_NAME_REQ *)NULL;
594
  RDPDR_HEADER * hdr = (RDPDR_HEADER *)NULL;
595
  DR_CORE_USER_LOGGEDON * ulo = (DR_CORE_USER_LOGGEDON *)NULL;
596
  DR_CORE_CAPABILITY_REQ * capreq = (DR_CORE_CAPABILITY_REQ *)NULL;
597
  CAPABILITY_SET * capset = (CAPABILITY_SET *)NULL;
598
  GENERAL_CAPS_SET * generalcap = (GENERAL_CAPS_SET *)NULL;
599
  PRINTER_CAPS_SET * printercap = (PRINTER_CAPS_SET *)NULL;
600
  PORT_CAPS_SET * portcap = (PORT_CAPS_SET *)NULL;
601
  DRIVE_CAPS_SET * drivecap = (DRIVE_CAPS_SET *)NULL;
602
  SMARTCARD_CAPS_SET * smartcardcap = (SMARTCARD_CAPS_SET *)NULL;
603
604
  int g_test_mode = 1;
605
  
606
  void * pdu = (void *)NULL;
607
608
  MDBGLOG("redir","INFO\t[%s()]: called [%d, %d]\n\t\t--- chan_is 0x%8.8x; "
609
      "chan_flags 0x%8.8x; length %d; total_length %d", __func__, g_getpid(), g_gettid(),
610
      chan_id, chan_flags, length, total_length);
611
612
  if ((chan_flags & 3) == 3)
613
  {
614
    ls = s;
615
  }
616
  else
617
  {
618
    if (chan_flags & 1)
619
    {
620
      init_stream(g_ins, total_length)
621
    }
622
    in_uint8a(s, g_ins->end, length);
623
    g_ins->end += length;
624
    if ((chan_flags & 2) == 0)
625
    {
626
      return 0;
627
    }
628
    ls = g_ins;
629
  }
630
  if (g_client_announce_reply_received < 1) {
631
    creply = RDPDR_NEW(DR_CORE_SERVER_ANNOUNCE_RSP);
632
    get_DR_CORE_SERVER_ANNOUNCE_RSP(creply, ls);
633
    g_client_id = creply->ClientId;
634
    g_client_announce_reply_received = 1;
635
    MDBGLOG("redir","\nINFO\t[%s()]: **** Header.Component = 0x%8.8x\n * Header.PacketId = 0x%8.8x\n * ClientId = 0x%8.8x\n * VersionMajor = 0x%8.8x\n * VersionMinor = 0x%8.8x\n",__func__,creply->Header.Component,creply->Header.PacketId,creply->ClientId,creply->VersionMajor,creply->VersionMinor);
636
  }
637
  else if (g_client_name_request_received < 1) {
638
    DR_CORE_CLIENT_NAME_REQ tname;
639
    //cname = RDPDR_NEW(DR_CORE_CLIENT_NAME_REQ);
640
    cname = &tname;
641
    g_memset(cname,0,sizeof(DR_CORE_CLIENT_NAME_REQ));
642
    construct_DR_CORE_CLIENT_NAME_REQ(cname);
643
    get_DR_CORE_CLIENT_NAME_REQ(cname, ls);
644
    g_client_name_request_received = 1;
645
    g_client_computer_name = (char *)g_malloc(sizeof(char) * cname->ComputerNameLen,1);
646
    if (cname->UnicodeFlag > 0) {
647
      for (idx = 0; idx < (cname->ComputerNameLen / 2); idx++) {
648
        g_client_computer_name[idx] = cname->ComputerName[(idx * 2)];
649
      }
650
    }
651
    else {
652
      for (idx = 0; idx < cname->ComputerNameLen; idx++) {
653
        g_client_computer_name[idx] = cname->ComputerName[idx];
654
      }
655
    }
656
    MDBGLOG("redir","\nINFO\t[%s()]: **** Header.Component = 0x%8.8x\n * Header.PacketId = 0x%8.8x\n * UnicodeFlag = 0x%8.8x\n * CodePage = 0x%8.8x\n * ComputerNameLen = 0x%8.8x\n * ComputerName = %s\n",__func__,cname->Header.Component,cname->Header.PacketId,cname->UnicodeFlag,cname->CodePage,cname->ComputerNameLen,g_client_computer_name);
657
658
    if (g_core_capabilities_requested < 1) {
659
      capreq = RDPDR_NEW(DR_CORE_CAPABILITY_REQ);
660
      capreq->numCapabilities = 5;
661
662
      generalcap = RDPDR_NEW(GENERAL_CAPS_SET);
663
      printercap = RDPDR_NEW(PRINTER_CAPS_SET);
664
      portcap = RDPDR_NEW(PORT_CAPS_SET);
665
      drivecap = RDPDR_NEW(DRIVE_CAPS_SET);
666
      smartcardcap = RDPDR_NEW(SMARTCARD_CAPS_SET);
667
668
      make_stream(ts);
669
      init_stream(ts, MAX_STREAM);
670
      send_RDPDR_HEADER(&(capreq->Header), ts);
671
      capreq->numCapabilities = 5;
672
      out_uint16_le(ts, capreq->numCapabilities);
673
      out_uint16_le(ts, capreq->Padding);
674
675
      generalcap->Header.CapabilityLength = 0x2c;
676
      generalcap->osType = 0x00000002;
677
      generalcap->osVersion = 0x00000000;
678
      generalcap->protocolMajorVersion = 0x0001;
679
      generalcap->protocolMinorVersion = 0x000c;
680
      generalcap->ioCode1 = 0x0000ffff;
681
      generalcap->ioCode2 = 0x00000000;
682
      generalcap->extendedPDU = 0x00000007;
683
      generalcap->extraFlags1 = ENABLE_ASYNCIO;
684
      generalcap->extraFlags2 = 0x00000000;
685
      generalcap->SpecialTypeDeviceCap = 0x00000002;
686
687
      out_uint16_le(ts, generalcap->Header.CapabilityType);
688
      out_uint16_le(ts, generalcap->Header.CapabilityLength);
689
      out_uint32_le(ts, generalcap->Header.Version);
690
      out_uint32_le(ts, generalcap->osType);
691
      out_uint32_le(ts, generalcap->osVersion);
692
      out_uint16_le(ts, generalcap->protocolMajorVersion);
693
      out_uint16_le(ts, generalcap->protocolMinorVersion);
694
      out_uint32_le(ts, generalcap->ioCode1);
695
      out_uint32_le(ts, generalcap->ioCode2);
696
      out_uint32_le(ts, generalcap->extendedPDU);
697
      out_uint32_le(ts, generalcap->extraFlags1);
698
      out_uint32_le(ts, generalcap->extraFlags2);
699
      out_uint32_le(ts, generalcap->SpecialTypeDeviceCap);
700
701
      out_uint16_le(ts, printercap->Header.CapabilityType);
702
      out_uint16_le(ts, printercap->Header.CapabilityLength);
703
      out_uint32_le(ts, printercap->Header.Version);
704
705
      out_uint16_le(ts, portcap->Header.CapabilityType);
706
      out_uint16_le(ts, portcap->Header.CapabilityLength);
707
      out_uint32_le(ts, portcap->Header.Version);
708
709
      out_uint16_le(ts, drivecap->Header.CapabilityType);
710
      out_uint16_le(ts, drivecap->Header.CapabilityLength);
711
      out_uint32_le(ts, drivecap->Header.Version);
712
713
      out_uint16_le(ts, smartcardcap->Header.CapabilityType);
714
      out_uint16_le(ts, smartcardcap->Header.CapabilityLength);
715
      out_uint32_le(ts, smartcardcap->Header.Version);
716
717
      s_mark_end(ts);
718
      size = (int)(ts->end - ts->data);
719
      TC_MUTEX_LOCK(mutex_out);
720
      rv = send_channel_data(g_rdpdr_chan_id, ts->data, size);
721
      TC_MUTEX_UNLOCK(mutex_out);
722
      MDBGLOG("redir","INFO\t[%s()]: ^^ DR_CORE_CAPABILITY_REQ sent (rv = %d).",__func__,rv);
723
      // g_hexdump_file("/tmp/redir_hexdump.log", ts->data, size);
724
      g_core_capabilities_requested = 1;
725
      //free_stream(ts);
726
    }
727
728
    if (g_user_loggedon_sent < 1) {
729
      ulo = RDPDR_NEW(DR_CORE_USER_LOGGEDON);
730
      make_stream(ts);
731
      init_stream(ts, MAX_STREAM);
732
      ulo->out(ulo, ts);
733
      s_mark_end(ts);
734
      size = (int)(ts->end - ts->data);
735
      TC_MUTEX_LOCK(mutex_out);
736
      rv = send_channel_data(g_rdpdr_chan_id, ts->data, size);
737
      TC_MUTEX_UNLOCK(mutex_out);
738
      MDBGLOG("redir","INFO\t[%s()]: ^^ DR_CORE_USER_LOGGEDON sent (rv = %d).",__func__,rv);
739
      g_user_loggedon_sent = 1;
740
      //free_stream(ts);
741
    }
742
  }
743
  else {
744
745
    RDPDR_HEADER thdr;
746
    g_memset(&thdr,0,sizeof(RDPDR_HEADER));
747
    hdr = &thdr;
748
    construct_RDPDR_HEADER(&thdr);
749
    get_RDPDR_HEADER(hdr, ls);
750
751
    MDBGLOG("redir", "INFO\t[%s()]: hdr->(Component = 0x%8.8x, PacketId = 0x%8.8x)", __func__, thdr.Component, thdr.PacketId);
752
753
    if (hdr->Component == RDPDR_CTYP_CORE) {
754
      switch (hdr->PacketId) {
755
	case PAKID_CORE_SERVER_ANNOUNCE:
756
	  MDBGLOG("redir","INFO\t[%s()]: - hdr->PacketId = 0x%8.8x (PAKID_CORE_SERVER_ANNOUNCE)",__func__,hdr->PacketId);
757
	  // rv = rdpdr_process_SERVER_ANNOUNCE(ls);
758
	  break;
759
	case PAKID_CORE_CLIENTID_CONFIRM:
760
	  MDBGLOG("redir","INFO\t[%s()]: - hdr->PacketId = 0x%8.8x (PAKID_CORE_CLIENTID_CONFIRM)",__func__,hdr->PacketId);
761
	  // rv = rdpdr_process_CLIENTID_CONFIRM(ls);
762
	  break;
763
	case PAKID_CORE_CLIENT_NAME:
764
	  MDBGLOG("redir","INFO\t[%s()]: - hdr->PacketId = 0x%8.8x (PAKID_CORE_CLIENT_NAME)",__func__,hdr->PacketId);
765
	  // rv = rdpdr_process_CLIENT_NAME(ls);
766
	  break;
767
	case PAKID_CORE_DEVICELIST_ANNOUNCE:
768
	  MDBGLOG("redir","INFO\t[%s()]: - hdr->PacketId = 0x%8.8x (PAKID_CORE_DEVICELIST_ANNOUNCE)",__func__,hdr->PacketId);
769
	  {
770
	    int j = 0;
771
	    int id = 0;
772
	    char * dname = (char *)NULL;
773
	    size = ls->end - ls->p;
774
	    // g_hexdump_file("/tmp/taskq_devicelist.hexdump", ls->p, size);
775
	    rv = rdpdr_process_DEVICELIST_ANNOUNCE(ls);
776
	    TC_MUTEX_LOCK(mutex_client_devicelist);
777
	    if (g_client_devicelist->DeviceCount > 0) {
778
	      MDBGLOG("redir","INFO\t[%s()]: - g_port_count = %d;\n - g_fs_count = %d;\n - g_client_devicelist->DeviceCount = %d\n",__func__,g_port_count,g_fs_count,g_client_devicelist->DeviceCount);
779
	      for (j = 0; j < g_client_devicelist->DeviceCount; j++) if (g_client_devicelist->DeviceList[j] != NULL) {
780
		id = g_client_devicelist->DeviceList[j]->DeviceId;
781
		dname = g_client_devicelist->DeviceList[j]->PreferredDosName;
782
		MDBGLOG("redir","\t[device #%d] - PreferredDosName = %s; DeviceId = 0x%8.8x",j,dname,id);
783
	      }
784
	      MDBGLOG("redir","\n");
785
	    }
786
	    TC_MUTEX_UNLOCK(mutex_client_devicelist);
787
	  }
788
          break;
789
	case PAKID_CORE_DEVICE_REPLY:
790
	  MDBGLOG("redir","INFO\t[%s()]: - hdr->PacketId = 0x%8.8x (PAKID_CORE_DEVICE_REPLY)",__func__,hdr->PacketId);
791
	  rv = rdpdr_process_DEVICE_REPLY(ls);
792
	  break;
793
	case PAKID_CORE_DEVICE_IOCOMPLETION:
794
	  MDBGLOG("redir","INFO\t[%s()]: - hdr->PacketId = 0x%8.8x (PAKID_CORE_DEVICE_IOCOMPLETION)",__func__,hdr->PacketId);
795
	  {
796
	    int opid = -1;
797
	    int tmp = 0;
798
	    int size = 0;
799
	    callback * cb = (callback *)NULL;
800
	    struct stream * t = (struct stream *)NULL;
801
	    struct stream * u = (struct stream *)NULL;
802
	    DEVICE_IOCOMPLETION ioc;
803
	    union _rsps {
804
	      DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP query_volume_information_rsp;
805
	      DR_DRIVE_QUERY_INFORMATION_RSP query_information_rsp;
806
	      DR_DRIVE_QUERY_DIRECTORY_RSP query_directory_rsp;
807
	      DR_DRIVE_SET_VOLUME_INFORMATION_RSP set_volume_information_rsp;
808
	      DR_DRIVE_SET_INFORMATION_RSP set_information_rsp;
809
	      DR_DRIVE_CLOSE_RSP close_rsp;
810
	      DR_DRIVE_CREATE_RSP drive_create_rsp;
811
	      DR_CREATE_RSP create_rsp;
812
	      DR_READ_RSP read_rsp;
813
	      DR_WRITE_RSP write_rsp;
814
	      DR_CONTROL_RSP control_rsp;
815
	    } rsps;
816
	    int new_opid = -1;
817
818
	    g_memset(&ioc,0,sizeof(DEVICE_IOCOMPLETION));
819
	    g_memset(&rsps,0,sizeof(union _rsps));
820
821
	    make_stream(u);
822
	    init_stream(u, MAX_STREAM);
823
824
	    construct_DR_DEVICE_IOCOMPLETION(&ioc);
825
	    ioc.Header.Component = hdr->Component;
826
	    ioc.Header.PacketId = hdr->PacketId;
827
	    in_uint32_le(ls, ioc.DeviceId);
828
	    in_uint32_le(ls, ioc.CompletionId);
829
	    in_uint32_le(ls, ioc.IoStatus.Value);
830
831
	    devidx = get_device_index(ioc.DeviceId);
832
	    opid = ioc.CompletionId;
833
834
	    TC_MUTEX_LOCK(mutex_cb);
835
	    cb = &(g_callbacks[opid]);
836
	    rdp_opcode = cb->opcode;
837
	    uniqid = cb->uniqid;
838
	    cb->IoStatus.Value = ioc.IoStatus.Value;
839
840
	    if (ioc.IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR) {
841
	      fault = 1;
842
	    }
843
	    else if (ioc.IoStatus.Value >= STATUS_UNSUCCESSFUL && ioc.IoStatus.Value <= STATUS_SXS_CORRUPTION) {
844
	      fault = 1;
845
	    }
846
	    if (fault > 0) {
847
	      getattr_queue_t * tmp = (getattr_queue_t *)NULL;
848
	      const char * nterr = (const char *)ntstatus_string(ioc.IoStatus.Value);
849
	      rdp_opcode |= RDP_ERROR;
850
	      out_uint32_le(u, ioc.IoStatus.Value);
851
	      s_mark_end(u);
852
	      size = u->end - u->data;
853
	      fhandle = cb->FileId;
854
	      if (rdp_opcode == RDPFS_GETATTR || rdp_opcode == RDPFS_FGETATTR) {
855
		device_id = (device_id > 0) ? device_id : g_client_devicelist->DeviceList[devidx]->DeviceId;
856
		GETATTR_FIND(device_id, opid, tmp);
857
		if (tmp != NULL) {
858
		  TC_MUTEX_LOCK(&(tmp->lock));
859
		  GETATTR_CUT(tmp);
860
		  TC_MUTEX_UNLOCK(&(tmp->lock));
861
		  TC_MUTEX_DEINIT(&(tmp->lock));
862
		  g_free(tmp);
863
		}
864
	      }
865
	      MDBGLOG("redir","INFO\t[%s()] (FAULT: \"%s\") reply: IoStatus = 0x%8.8x; rdp_opcode = 0x%8.8x; device_id = 0x%8.8x; fhandle = %d; uniqid = %d",__func__,nterr,ioc.IoStatus.Value,rdp_opcode,device_id,fhandle,uniqid);
866
	    }
867
	    else if (rdp_opcode == RDPFS_INIT || rdp_opcode == RDPPORT_INIT) {
868
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
869
	      rsp = &rsps.drive_create_rsp;
870
	      construct_DR_DRIVE_CREATE_RSP(rsp);
871
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
872
	      in_uint32_le(ls, rsp->DeviceCreateResponse.FileId);
873
	      in_uint8(ls, rsp->DeviceCreateResponse.Information);
874
	      cb->FileId = rsp->DeviceCreateResponse.FileId;
875
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
876
	      s_mark_end(u);
877
	      size = u->end - u->data;
878
	      fhandle = rsp->DeviceCreateResponse.FileId;
879
	      MDBGLOG("redir","INFO\t[%s()] (RDPFS_INIT) reply: FileId = %d; Information = %d",__func__,rsp->DeviceCreateResponse.FileId,rsp->DeviceCreateResponse.Information);
880
	    }
881
	    else if (rdp_opcode == RDPFS_OPENDIR) {
882
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
883
	      rsp = &rsps.drive_create_rsp;
884
	      construct_DR_DRIVE_CREATE_RSP(rsp);
885
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
886
	      in_uint32_le(ls, rsp->DeviceCreateResponse.FileId);
887
	      in_uint8(ls, rsp->DeviceCreateResponse.Information);
888
	      cb->FileId = rsp->DeviceCreateResponse.FileId;
889
	      fhandle = rsp->DeviceCreateResponse.FileId;
890
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
891
	      s_mark_end(u);
892
	      size = u->end - u->data;
893
	    }
894
	    else if (rdp_opcode == RDPFS_READDIR) {
895
	      int warning = 0;
896
	      DR_DRIVE_QUERY_DIRECTORY_RSP * rsp = (DR_DRIVE_QUERY_DIRECTORY_RSP *)NULL;
897
	      rsp = &rsps.query_directory_rsp;
898
	      fhandle = cb->FileId;
899
	      {
900
		int i = 0;
901
		int zlen = 0;
902
		FILE_BOTH_DIR_INFORMATION * dirinfo = (FILE_BOTH_DIR_INFORMATION *)NULL;
903
		LOCAL_STREAM(zs);
904
		construct_DR_DRIVE_QUERY_DIRECTORY_RSP(rsp);
905
		g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
906
		rsp->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
907
		rsp->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
908
		rsp->out = &send_DR_DRIVE_QUERY_DIRECTORY_RSP;
909
		in_uint32_le(ls, rsp->Length);
910
		if (rsp->Length > 0) {
911
		  get_FILE_BOTH_DIR_INFORMATION(&(rsp->Buffer.both), ls);
912
		}
913
		if (rsp->Buffer.both.NextEntryOffset == 0) {
914
		  rsp->Buffer.both.NextEntryOffset = rsp->Length;
915
		}
916
		if (ioc.IoStatus.Value == STATUS_NO_MORE_FILES) {
917
		  g_no_more_files = 1;
918
		}
919
		send_DR_DRIVE_QUERY_DIRECTORY_RSP(rsp, u);
920
		s_mark_end(u);
921
		size = u->end - u->data;
922
		if (g_no_more_files < 1) {
923
		  LOCAL_STREAM(r);
924
		  DR_DRIVE_QUERY_DIRECTORY_REQ ioreq;
925
		  construct_DR_DRIVE_QUERY_DIRECTORY_REQ(&ioreq);
926
		  ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
927
		  ioreq.DeviceIoRequest.MinorFunction = IRP_MN_QUERY_DIRECTORY;
928
		  TC_MUTEX_LOCK(mutex_client_devicelist);
929
		  TC_MUTEX_LOCK(mutex_fs_arr);
930
		  if (g_client_devicelist != NULL && g_client_devicelist->DeviceList != NULL && g_client_devicelist->DeviceList[devidx] != NULL) {
931
		    ioreq.DeviceIoRequest.DeviceId = g_client_devicelist->DeviceList[devidx]->DeviceId;
932
		  }
933
		  else if (g_fs_arr != NULL && g_fs_arr[0] != NULL) {
934
		    ioreq.DeviceIoRequest.DeviceId = g_fs_arr[0]->device_id;
935
		  }
936
		  TC_MUTEX_UNLOCK(mutex_client_devicelist);
937
		  ioreq.DeviceIoRequest.FileId = fhandle;
938
		  new_opid = get_opid(g_fs_arr[devidx]);
939
		  TC_MUTEX_UNLOCK(mutex_fs_arr);
940
		  ioreq.DeviceIoRequest.CompletionId = new_opid;
941
		  ioreq.FsInformationClass = FileBothDirectoryInformation;
942
		  ioreq.InitialQuery = 0x00;
943
		  ioreq.PathLength = 0;
944
		  g_memcpy((callback *)(&(g_callbacks[new_opid])),(callback *)(&(g_callbacks[opid])),sizeof(callback));
945
		  g_callbacks[new_opid].opid = new_opid;
946
		  g_callbacks[new_opid].CompletionId = new_opid;
947
		  g_memset(&(g_callbacks[opid]),0,sizeof(callback));
948
		  g_callbacks[opid].opid = -1;
949
		  send_DR_DRIVE_QUERY_DIRECTORY_REQ(&ioreq, r);
950
		  s_mark_end(r);
951
		  TC_MUTEX_LOCK(mutex_out);
952
		  send_channel_data(g_rdpdr_chan_id, r->data, (int)(r->end - r->data));
953
		  TC_MUTEX_UNLOCK(mutex_out);
954
		}
955
		else {
956
		  g_no_more_files = 0;
957
		}
958
	      }
959
	    }
960
	    else if (rdp_opcode == RDPFS_RELEASEDIR) {
961
	      DR_DRIVE_CLOSE_RSP * rsp = (DR_DRIVE_CLOSE_RSP *)NULL;
962
	      rsp = &rsps.close_rsp;
963
	      g_memcpy(&(rsp->DeviceCloseResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
964
	      construct_DR_DRIVE_CLOSE_RSP(rsp);
965
	      send_DR_DRIVE_CLOSE_RSP(rsp, u);
966
	      s_mark_end(u);
967
	      size = u->end - u->data;
968
	      //MDBGLOG("redir","INFO\t[%s()]: (RDPFS_RELEASEDIR) reply",__func__);
969
	    }
970
	    else if (rdp_opcode == RDPFS_CREATE) {
971
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
972
	      rsp = &rsps.drive_create_rsp;
973
	      construct_DR_DRIVE_CREATE_RSP(rsp);
974
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
975
	      in_uint32_le(ls, rsp->DeviceCreateResponse.FileId);
976
	      in_uint8(ls, rsp->DeviceCreateResponse.Information);
977
	      cb->FileId = rsp->DeviceCreateResponse.FileId;
978
	      fhandle = rsp->DeviceCreateResponse.FileId;
979
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
980
	      s_mark_end(u);
981
	      size = u->end - u->data;
982
	      MDBGLOG("parent","INFO\t[%s()] (RDPFS_CREATE) reply: FileId = %d; Information = %d; fhandle = %d",__func__,rsp->DeviceCreateResponse.FileId,rsp->DeviceCreateResponse.Information,fhandle);
983
	      //MDBGLOG("redir","INFO\t[%s()]: (RDPFS_CREATE) reply",__func__);
984
	    }
985
	    else if (rdp_opcode == RDPFS_OPEN || rdp_opcode == RDPPORT_OPEN) {
986
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
987
	      rsp = &rsps.drive_create_rsp;
988
	      construct_DR_DRIVE_CREATE_RSP(rsp);
989
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
990
	      in_uint32_le(ls, rsp->DeviceCreateResponse.FileId);
991
	      in_uint8(ls, rsp->DeviceCreateResponse.Information);
992
	      cb->FileId = rsp->DeviceCreateResponse.FileId;
993
	      fhandle = rsp->DeviceCreateResponse.FileId;
994
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
995
	      s_mark_end(u);
996
	      size = u->end - u->data;
997
	      //MDBGLOG("parent","INFO\t[%s()]: (RDPFS_OPEN) reply (FileId = %d; Information = %d; fhandle = %d)",__func__,rsp->DeviceCreateResponse.FileId,rsp->DeviceCreateResponse.Information,fhandle);
998
	      //// g_hexdump_file("/tmp/taskq_dev_open.hexdump",u->data,size);
999
	    }
1000
	    else if (rdp_opcode == RDPFS_READ || rdp_opcode == RDPPORT_READ) {
1001
	      DR_DRIVE_READ_RSP * rsp = (DR_DRIVE_READ_RSP *)NULL;
1002
	      rsp = &rsps.read_rsp;
1003
	      construct_DR_READ_RSP(rsp);
1004
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1005
	      rsp->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
1006
	      rsp->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
1007
	      rsp->out = &send_DR_READ_RSP;
1008
	      in_uint32_le(ls, rsp->Length);
1009
	      if (rsp->Length > 0) {
1010
		rsp->ReadData = (BYTE *)g_malloc(sizeof(BYTE) * rsp->Length, 1);
1011
		in_uint8a(ls, rsp->ReadData, rsp->Length);
1012
	      }
1013
	      send_DR_READ_RSP(rsp, u);
1014
	      s_mark_end(u);
1015
	      size = u->end - u->data;
1016
	      // g_hexdump_file("/tmp/taskq_read.hexdump", u->data, size);
1017
	      MDBGLOG("redir","INFO\t[%s()] (RDPFS_READ) reply (size = %d; rsp->Length = %d; rsp->ReadData = \"%s\"; rsp->DeviceIoReply.IoStatus = 0x%8.8x)",__func__,size,rsp->Length,rsp->ReadData,rsp->DeviceIoReply.IoStatus.Value);
1018
	    }
1019
	    else if (rdp_opcode == RDPFS_WRITE || rdp_opcode == RDPPORT_WRITE) {
1020
	      DR_DRIVE_WRITE_RSP * rsp = (DR_DRIVE_WRITE_RSP *)NULL;
1021
	      rsp = &rsps.write_rsp;
1022
	      construct_DR_WRITE_RSP(rsp);
1023
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1024
	      rsp->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
1025
	      rsp->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
1026
	      rsp->out = &send_DR_WRITE_RSP;
1027
	      in_uint32_le(ls, rsp->Length);
1028
	      send_DR_WRITE_RSP(rsp, u);
1029
	      s_mark_end(u);
1030
	      size = u->end - u->data;
1031
	      MDBGLOG("redir","INFO\t[%s()] (RDPFS_WRITE) reply",__func__);
1032
	    }
1033
	    else if (rdp_opcode == RDPFS_GETATTR || rdp_opcode == RDPFS_FGETATTR) {
1034
	      getattr_queue_t * tmp = (getattr_queue_t *)NULL;
1035
	      DR_DRIVE_QUERY_INFORMATION_RSP * rsp = (DR_DRIVE_QUERY_INFORMATION_RSP *)NULL;
1036
	      DR_DRIVE_QUERY_INFORMATION_REQ ioreq;
1037
	      LOCAL_STREAM(r);
1038
	      rsp = &(rsps.query_information_rsp);
1039
	      construct_DR_DRIVE_QUERY_INFORMATION_RSP(rsp);
1040
	      g_memcpy(rsp, &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1041
	      g_memset(&ioreq,0,sizeof(DR_DRIVE_QUERY_INFORMATION_REQ));
1042
	      TC_MUTEX_LOCK(mutex_client_devicelist);
1043
	      device_id = (device_id > 0) ? device_id : g_client_devicelist->DeviceList[devidx]->DeviceId;
1044
	      TC_MUTEX_UNLOCK(mutex_client_devicelist);
1045
	      TC_MUTEX_LOCK(mutex_getattr);
1046
	      GETATTR_FIND(device_id, opid, tmp);
1047
	      if (tmp == NULL) {
1048
		tmp = GETATTR_CREATE();
1049
		if (tmp != NULL) {
1050
		  GETATTR_INIT(tmp);
1051
		  TC_MUTEX_LOCK(&(tmp->lock));
1052
		  tmp->basic_done = 0;
1053
		  tmp->device_id = device_id;
1054
		  tmp->uniqid = uniqid;
1055
		  tmp->opid = opid;
1056
		  tmp->fhandle = g_callbacks[opid].FileId;
1057
		  TC_MUTEX_UNLOCK(&(tmp->lock));
1058
		}
1059
	      }
1060
	      if (tmp->basic_done < 1) {
1061
		TC_MUTEX_LOCK(&(tmp->lock));
1062
		rsp = &(tmp->rsp);
1063
		g_memset(rsp,0,sizeof(DR_DRIVE_QUERY_INFORMATION_RSP));
1064
		construct_DR_DRIVE_QUERY_INFORMATION_RSP(rsp);
1065
		g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1066
		rsp->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
1067
		rsp->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
1068
		rsp->out = &send_DR_DRIVE_QUERY_INFORMATION_RSP;
1069
		in_uint32_le(ls, rsp->Length);
1070
		if (rsp->Length > 0) {
1071
		  in_uint8a(ls, &(rsp->Buffer.all.BasicInformation), rsp->Length);
1072
		}
1073
		suppress = 1;
1074
		tmp->basic_done = 1;
1075
		construct_DR_DRIVE_QUERY_INFORMATION_REQ(&ioreq);
1076
		ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_QUERY_INFORMATION;
1077
		TC_MUTEX_LOCK(mutex_client_devicelist);
1078
		TC_MUTEX_LOCK(mutex_fs_arr);
1079
		if (g_client_devicelist != NULL && g_client_devicelist->DeviceList != NULL && g_client_devicelist->DeviceList[devidx] != NULL) {
1080
		  ioreq.DeviceIoRequest.DeviceId = g_client_devicelist->DeviceList[devidx]->DeviceId;
1081
		}
1082
		else if (g_fs_arr != NULL && g_fs_arr[0] != NULL) {
1083
		  ioreq.DeviceIoRequest.DeviceId = g_fs_arr[0]->device_id;
1084
		}
1085
		TC_MUTEX_UNLOCK(mutex_fs_arr);
1086
		TC_MUTEX_UNLOCK(mutex_client_devicelist);
1087
		new_opid = opid;
1088
		ioreq.DeviceIoRequest.CompletionId = new_opid;
1089
		g_callbacks[new_opid].opid = new_opid;
1090
		g_callbacks[new_opid].CompletionId = new_opid;
1091
		g_callbacks[new_opid].uniqid = g_callbacks[opid].uniqid;
1092
		g_callbacks[new_opid].FileId = g_callbacks[opid].FileId;
1093
		ioreq.DeviceIoRequest.FileId = tmp->fhandle;
1094
		ioreq.FsInformationClass = FileStandardInformation;
1095
		send_DR_DRIVE_QUERY_INFORMATION_REQ(&ioreq, r);
1096
		s_mark_end(r);
1097
		TC_MUTEX_LOCK(mutex_out);
1098
		send_channel_data(g_rdpdr_chan_id, r->data, (int)(r->end - r->data));
1099
		TC_MUTEX_UNLOCK(mutex_out);
1100
		tmp->uniqid = uniqid;
1101
		tmp->opid = opid;
1102
		tmp->opcode = rdp_opcode;
1103
		g_callbacks[opid].opid = 0;
1104
		TC_MUTEX_UNLOCK(&(tmp->lock));
1105
	      }
1106
	      else {
1107
		int len = 0;
1108
		char * iptr = NULL;
1109
		char * optr = NULL;
1110
		int inum = 0;
1111
		int onum = 0;
1112
		TC_MUTEX_LOCK(&(tmp->lock));
1113
		rsp = &(tmp->rsp);
1114
		in_uint32_le(ls, len);
1115
		if (len > 0) {
1116
		  in_uint8a(ls, &(rsp->Buffer.all.StandardInformation), len);
1117
		}
1118
		rsp->Buffer.all.NameInformation.FileNameLength = (g_strlen(g_callbacks[opid].fname) + 1) * 2;
1119
		iptr = g_callbacks[opid].fname;
1120
		optr = rsp->Buffer.all.NameInformation.FileName;
1121
		inum = g_strlen(g_callbacks[opid].fname);
1122
		onum = rsp->Buffer.all.NameInformation.FileNameLength;
1123
		g_outstr(&optr, &onum, &iptr, &inum);
1124
		uniqid = tmp->uniqid;
1125
		rdp_opcode |= tmp->opcode;
1126
		rsp->Length = sizeof(FILE_ALL_INFORMATION) + rsp->Buffer.all.NameInformation.FileNameLength;
1127
		send_DR_DRIVE_QUERY_INFORMATION_RSP(rsp, u);
1128
		s_mark_end(u);
1129
		size = u->end - u->data;
1130
		tmp->basic_done = 0;
1131
		GETATTR_CUT(tmp);
1132
		TC_MUTEX_UNLOCK(&(tmp->lock));
1133
		TC_MUTEX_DEINIT(&(tmp->lock));
1134
		g_free(tmp);
1135
	      }
1136
	      TC_MUTEX_UNLOCK(mutex_getattr);
1137
	    }
1138
	    else if (rdp_opcode == RDPFS_SETATTR) {
1139
	      DR_DRIVE_CONTROL_RSP * rsp = (DR_DRIVE_CONTROL_RSP *)NULL;
1140
	      rsp = &rsps.control_rsp;
1141
	      construct_DR_CONTROL_RSP(rsp);
1142
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1143
	      send_DR_CONTROL_RSP(rsp, u);
1144
	      s_mark_end(u);
1145
	      size = u->end - u->data;
1146
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_SETATTR) reply",__func__);
1147
	    }
1148
	    else if (rdp_opcode == RDPFS_MKNOD) {
1149
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
1150
	      rsp = &rsps.drive_create_rsp;
1151
	      construct_DR_DRIVE_CREATE_RSP(rsp);
1152
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1153
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
1154
	      s_mark_end(u);
1155
	      size = u->end - u->data;
1156
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_MKNOD) reply",__func__);
1157
	    }
1158
	    else if (rdp_opcode == RDPFS_MKDIR) {
1159
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
1160
	      rsp = &rsps.drive_create_rsp;
1161
	      construct_DR_DRIVE_CREATE_RSP(rsp);
1162
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1163
	      in_uint32_le(ls, rsp->DeviceCreateResponse.FileId);
1164
	      in_uint8(ls, rsp->DeviceCreateResponse.Information);
1165
	      cb->FileId = rsp->DeviceCreateResponse.FileId;
1166
	      fhandle = rsp->DeviceCreateResponse.FileId;
1167
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
1168
	      s_mark_end(u);
1169
	      size = u->end - u->data;
1170
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_MKDIR) replying: FileId = %d; fhandle = %d",__func__,rsp->DeviceCreateResponse.FileId,fhandle);
1171
	    }
1172
	    else if (rdp_opcode == RDPFS_UNLINK) {
1173
	      DR_DRIVE_SET_INFORMATION_RSP * rsp = (DR_DRIVE_SET_INFORMATION_RSP *)NULL;
1174
	      rsp = &rsps.set_information_rsp;
1175
	      construct_DR_DRIVE_SET_INFORMATION_RSP(rsp);
1176
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1177
	      send_DR_DRIVE_SET_INFORMATION_RSP(rsp, u);
1178
	      s_mark_end(u);
1179
	      size = u->end - u->data;
1180
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_UNLINK) reply",__func__,rsp->Length);
1181
	    }
1182
	    else if (rdp_opcode == RDPFS_RELEASE || rdp_opcode == RDPPORT_CLOSE) {
1183
	      DR_DRIVE_CLOSE_RSP * rsp = (DR_DRIVE_CLOSE_RSP *)NULL;
1184
	      rsp = &rsps.close_rsp;
1185
	      construct_DR_DRIVE_CLOSE_RSP(rsp);
1186
	      g_memcpy(&(rsp->DeviceCloseResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1187
	      send_DR_DRIVE_CLOSE_RSP(rsp, u);
1188
	      s_mark_end(u);
1189
	      size = u->end - u->data;
1190
	    }
1191
	    else if (rdp_opcode == RDPFS_RMDIR) {
1192
	      DR_DRIVE_SET_INFORMATION_RSP * rsp = (DR_DRIVE_SET_INFORMATION_RSP *)NULL;
1193
	      rsp = &rsps.set_information_rsp;
1194
	      construct_DR_DRIVE_SET_INFORMATION_RSP(rsp);
1195
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1196
	      send_DR_DRIVE_SET_INFORMATION_RSP(rsp, u);
1197
	      s_mark_end(u);
1198
	      size = u->end - u->data;
1199
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_RMDIR) reply",__func__);
1200
	    }
1201
	    else if (rdp_opcode == RDPFS_SYMLINK) {
1202
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
1203
	      rsp = &rsps.drive_create_rsp;
1204
	      construct_DR_DRIVE_CREATE_RSP(rsp);
1205
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1206
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
1207
	      s_mark_end(u);
1208
	      size = u->end - u->data;
1209
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_SYMLINK) reply",__func__);
1210
	    }
1211
	    else if (rdp_opcode == RDPFS_RENAME) {
1212
	      DR_DRIVE_SET_INFORMATION_RSP * rsp = (DR_DRIVE_SET_INFORMATION_RSP *)NULL;
1213
	      rsp = &rsps.set_information_rsp;
1214
	      construct_DR_DRIVE_SET_INFORMATION_RSP(rsp);
1215
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1216
	      send_DR_DRIVE_SET_INFORMATION_RSP(rsp, u);
1217
	      s_mark_end(u);
1218
	      size = u->end - u->data;
1219
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_RENAME) reply",__func__);
1220
	    }
1221
	    else if (rdp_opcode == RDPFS_LINK) {
1222
	      DR_DRIVE_CREATE_RSP * rsp = (DR_DRIVE_CREATE_RSP *)NULL;
1223
	      rsp = &rsps.drive_create_rsp;
1224
	      construct_DR_DRIVE_CREATE_RSP(rsp);
1225
	      g_memcpy(&(rsp->DeviceCreateResponse.DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1226
	      send_DR_DRIVE_CREATE_RSP(rsp, u);
1227
	      s_mark_end(u);
1228
	      size = u->end - u->data;
1229
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_LINK) reply",__func__);
1230
	    }
1231
	    else if (rdp_opcode == RDPFS_CHMOD) {
1232
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1233
	      rsp = &rsps.control_rsp;
1234
	      construct_DR_CONTROL_RSP(rsp);
1235
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1236
	      send_DR_CONTROL_RSP(rsp, u);
1237
	      s_mark_end(u);
1238
	      size = u->end - u->data;
1239
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_CHMOD) reply",__func__);
1240
	    }
1241
	    else if (rdp_opcode == RDPFS_CHOWN) {
1242
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1243
	      rsp = &rsps.control_rsp;
1244
	      construct_DR_CONTROL_RSP(rsp);
1245
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1246
	      send_DR_CONTROL_RSP(rsp, u);
1247
	      s_mark_end(u);
1248
	      size = u->end - u->data;
1249
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_CHOWN) reply",__func__);
1250
	    }
1251
	    else if (rdp_opcode == RDPFS_TRUNCATE) {
1252
	      DR_DRIVE_SET_INFORMATION_RSP * rsp = (DR_DRIVE_SET_INFORMATION_RSP *)NULL;
1253
	      rsp = &rsps.set_information_rsp;
1254
	      construct_DR_DRIVE_SET_INFORMATION_RSP(rsp);
1255
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1256
	      in_uint32_le(ls, rsp->Length);
1257
	      send_DR_DRIVE_SET_INFORMATION_RSP(rsp, u);
1258
	      s_mark_end(u);
1259
	      size = u->end - u->data;
1260
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_TRUNCATE) reply",__func__);
1261
	    }
1262
	    else if (rdp_opcode == RDPFS_UTIME) {
1263
	      callback * lcb = (callback *)NULL;
1264
	      lcb = &(g_callbacks[opid]);
1265
	      if (lcb->userdata != NULL) {
1266
		DR_DRIVE_SET_INFORMATION_RSP * rsp = (DR_DRIVE_SET_INFORMATION_RSP *)NULL;
1267
		rsp = &rsps.set_information_rsp;
1268
		construct_DR_DRIVE_SET_INFORMATION_RSP(rsp);
1269
		g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1270
		send_DR_DRIVE_SET_INFORMATION_RSP(rsp, u);
1271
		s_mark_end(u);
1272
		size = u->end - u->data;
1273
		g_free(lcb->userdata);
1274
		lcb->userdata = NULL;
1275
		MDBGLOG("redir","INFO\t[%s()]: (RDPFS_UTIME) reply",__func__);
1276
	      }
1277
	      else {
1278
		DR_DRIVE_SET_INFORMATION_REQ ioreq;
1279
		FILE_BASIC_INFORMATION * finfo;
1280
		int len = 0;
1281
		struct tm * t1 = NULL;
1282
		struct tm * t2 = NULL;
1283
		struct tm * t3 = NULL;
1284
		struct tm * t4 = NULL;
1285
		char * ttime1 = NULL;
1286
		char * ttime2 = NULL;
1287
		char * ttime3 = NULL;
1288
		char * ttime4 = NULL;
1289
		time_t tt1 = 0;
1290
		time_t tt2 = 0;
1291
		time_t tt3 = 0;
1292
		time_t tt4 = 0;
1293
		LOCAL_STREAM(r);
1294
1295
		suppress = 1;
1296
1297
		finfo = g_malloc(sizeof(FILE_BASIC_INFORMATION), 1);
1298
		lcb->userdata = (BYTE *)finfo;
1299
		in_uint32_le(ls, len);
1300
		if (len > 0) {
1301
		  in_uint8a(ls,finfo,len);
1302
		}
1303
1304
		construct_DR_DRIVE_SET_INFORMATION_REQ(&ioreq);
1305
		ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
1306
		TC_MUTEX_LOCK(mutex_client_devicelist);
1307
		TC_MUTEX_LOCK(mutex_fs_arr);
1308
		if (g_client_devicelist != NULL && g_client_devicelist->DeviceList != NULL && g_client_devicelist->DeviceList[devidx] != NULL) {
1309
		  ioreq.DeviceIoRequest.DeviceId = g_client_devicelist->DeviceList[devidx]->DeviceId;
1310
		}
1311
		else if (g_fs_arr != NULL && g_fs_arr[0] != NULL) {
1312
		  ioreq.DeviceIoRequest.DeviceId = g_fs_arr[0]->device_id;
1313
		}
1314
		TC_MUTEX_UNLOCK(mutex_fs_arr);
1315
		TC_MUTEX_UNLOCK(mutex_client_devicelist);
1316
		ioreq.DeviceIoRequest.CompletionId = opid;
1317
		ioreq.DeviceIoRequest.FileId = lcb->FileId;
1318
		ioreq.FsInformationClass = FileBasicInformation;
1319
		ioreq.Length = sizeof(FILE_BASIC_INFORMATION);
1320
1321
		lcb->opcode = RDPFS_UTIME;
1322
1323
		ioreq.SetBuffer.BasicInformation.CreationTime = finfo->CreationTime;
1324
		ioreq.SetBuffer.BasicInformation.LastAccessTime = lcb->actime;
1325
		ioreq.SetBuffer.BasicInformation.LastWriteTime = lcb->modtime;
1326
		ioreq.SetBuffer.BasicInformation.ChangeTime = finfo->ChangeTime;
1327
		ioreq.SetBuffer.BasicInformation.FileAttributes = finfo->FileAttributes;
1328
		send_DR_DRIVE_SET_INFORMATION_REQ(&ioreq, r);
1329
		s_mark_end(r);
1330
		TC_MUTEX_LOCK(mutex_out);
1331
		send_channel_data(g_rdpdr_chan_id, r->data, (int)(r->end - r->data));
1332
		TC_MUTEX_UNLOCK(mutex_out);
1333
		{
1334
		  tt1 = FileTimeToUnix(ioreq.SetBuffer.BasicInformation.LastAccessTime);
1335
		  tt2 = FileTimeToUnix(ioreq.SetBuffer.BasicInformation.LastWriteTime);
1336
		  tt3 = FileTimeToUnix(ioreq.SetBuffer.BasicInformation.CreationTime);
1337
		  tt4 = FileTimeToUnix(ioreq.SetBuffer.BasicInformation.ChangeTime);
1338
		  t1 = gmtime(&tt1);
1339
		  t2 = gmtime(&tt2);
1340
		  t3 = gmtime(&tt3);
1341
		  t4 = gmtime(&tt4);
1342
		  ttime1 = asctime(t1);
1343
		  ttime2 = asctime(t2);
1344
		  ttime3 = asctime(t3);
1345
		  ttime4 = asctime(t4);
1346
		  MDBGLOG("redir"," ^^ (RDPFS_UTIME): ioreq.Length = %d; buf = \"%s\"; ioreq.DeviceIoRequest.FileId = %d; ioreq.SetBuffer.BasicInformation.LastAccessTime = %s; ioreq.SetBuffer.BasicInformation.LastWriteTime = %s; CreationTime = %s; ChangeTime = %s",ioreq.Length,buf,ioreq.DeviceIoRequest.FileId,ttime1,ttime2,ttime3,ttime4);
1347
		}
1348
	      }
1349
	    }
1350
	    else if (rdp_opcode == RDPFS_STATFS) {
1351
	      DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP * rsp = (DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP *)NULL;
1352
	      rsp = &(rsps.query_volume_information_rsp);
1353
	      construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(rsp);
1354
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1355
	      in_uint32_le(ls, rsp->Length);
1356
	      if (rsp->Length > 0) {
1357
		in_uint8a(ls, (char *)(rsp->Buffer.bytes), rsp->Length);
1358
	      }
1359
	      send_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(rsp, u);
1360
	      s_mark_end(u);
1361
	      size = u->end - u->data;
1362
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_STATFS) reply",__func__);
1363
	    }
1364
	    else if (rdp_opcode == RDPFS_FLUSH) {
1365
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1366
	      rsp = &rsps.control_rsp;
1367
	      construct_DR_CONTROL_RSP(rsp);
1368
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1369
	      send_DR_CONTROL_RSP(rsp, u);
1370
	      s_mark_end(u);
1371
	      size = u->end - u->data;
1372
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_FLUSH) reply",__func__);
1373
	    }
1374
	    else if (rdp_opcode == RDPFS_FSYNC) {
1375
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1376
	      rsp = &rsps.control_rsp;
1377
	      construct_DR_CONTROL_RSP(rsp);
1378
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1379
	      send_DR_CONTROL_RSP(rsp, u);
1380
	      s_mark_end(u);
1381
	      size = u->end - u->data;
1382
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_FSYNC) reply",__func__);
1383
	    }
1384
	    else if (rdp_opcode == RDPFS_FSCTL) {
1385
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1386
	      rsp = &rsps.control_rsp;
1387
	      construct_DR_CONTROL_RSP(rsp);
1388
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1389
	      rsp->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
1390
	      rsp->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
1391
	      rsp->out = &send_DR_CONTROL_RSP;
1392
	      in_uint32_le(ls, rsp->OutputBufferLength);
1393
	      if (rsp->OutputBufferLength > 0) {
1394
		rsp->OutputBuffer = (BYTE *)g_malloc(sizeof(BYTE) * rsp->OutputBufferLength, 1);
1395
		in_uint8a(ls, rsp->OutputBuffer, rsp->OutputBufferLength);
1396
	      }
1397
	      send_DR_CONTROL_RSP(rsp, u);
1398
	      s_mark_end(u);
1399
	      size = u->end - u->data;
1400
	      // g_hexdump_file("/tmp/taskq_fsctl.hexdump", u->data, size);
1401
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_FSCTL) reply (size = %d; rsp->OutputBufferLength = %d; rsp->DeviceIoReply.IoStatus = 0x%8.8x)",__func__,size,rsp->OutputBufferLength,rsp->DeviceIoReply.IoStatus.Value);
1402
	    }
1403
	    else if (rdp_opcode == RDPPORT_IOCTL) {
1404
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1405
	      rsp = &rsps.control_rsp;
1406
	      construct_DR_CONTROL_RSP(rsp);
1407
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1408
	      rsp->DeviceIoReply.Header.out = &send_RDPDR_HEADER;
1409
	      rsp->DeviceIoReply.out = &send_DR_DEVICE_IOCOMPLETION;
1410
	      rsp->out = &send_DR_CONTROL_RSP;
1411
	      in_uint32_le(ls, rsp->OutputBufferLength);
1412
	      if (rsp->OutputBufferLength > 0) {
1413
		rsp->OutputBuffer = (BYTE *)g_malloc(sizeof(BYTE) * rsp->OutputBufferLength, 1);
1414
		in_uint8a(ls, rsp->OutputBuffer, rsp->OutputBufferLength);
1415
	      }
1416
	      send_DR_CONTROL_RSP(rsp, u);
1417
	      s_mark_end(u);
1418
	      size = u->end - u->data;
1419
	      // g_hexdump_file("/tmp/taskq_port_ioctl_rsp.hexdump", u->data, size);
1420
	      MDBGLOG("redir","INFO\t[%s()]: (RDPPORT_IOCTL) reply (size = %d; rsp->OutputBufferLength = %d; rsp->DeviceIoReply.IoStatus = 0x%8.8x)",__func__,size,rsp->OutputBufferLength,rsp->DeviceIoReply.IoStatus.Value);
1421
	    }
1422
	    else if (rdp_opcode == RDPFS_GETXATTR) {
1423
	      DR_DRIVE_QUERY_INFORMATION_RSP * rsp = (DR_DRIVE_QUERY_INFORMATION_RSP *)NULL;
1424
	      rsp = &rsps.query_information_rsp;
1425
	      construct_DR_DRIVE_QUERY_INFORMATION_RSP(rsp);
1426
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1427
	      send_DR_DRIVE_QUERY_INFORMATION_RSP(rsp, u);
1428
	      s_mark_end(u);
1429
	      size = u->end - u->data;
1430
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_GETXATTR) reply",__func__);
1431
	    }
1432
	    else if (rdp_opcode == RDPFS_SETXATTR) {
1433
	    }
1434
	    else if (rdp_opcode == RDPFS_LISTXATTR) {
1435
	    }
1436
	    else if (rdp_opcode == RDPFS_REMOVEXATTR) {
1437
	    }
1438
	    else if (rdp_opcode == RDPFS_FSYNCDIR) {
1439
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1440
	      rsp = &rsps.control_rsp;
1441
	      construct_DR_CONTROL_RSP(rsp);
1442
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1443
	      rsp->out(rsp, u);
1444
	      s_mark_end(u);
1445
	      size = u->end - u->data;
1446
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_FSYNCDIR) reply",__func__);
1447
	    }
1448
	    else if (rdp_opcode == RDPFS_ACCESS) {
1449
	      DR_CONTROL_RSP * rsp = (DR_CONTROL_RSP *)NULL;
1450
	      rsp = &rsps.control_rsp;
1451
	      construct_DR_CONTROL_RSP(rsp);
1452
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1453
	      send_DR_CONTROL_RSP(rsp, u);
1454
	      s_mark_end(u);
1455
	      size = u->end - u->data;
1456
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_ACCESS) reply",__func__);
1457
	    }
1458
	    else if (rdp_opcode == RDPFS_FTRUNCATE) {
1459
	      DR_DRIVE_SET_INFORMATION_RSP * rsp = (DR_DRIVE_SET_INFORMATION_RSP *)NULL;
1460
	      rsp = &rsps.set_information_rsp;
1461
	      construct_DR_DRIVE_SET_INFORMATION_RSP(rsp);
1462
	      g_memcpy(&(rsp->DeviceIoReply), &ioc, sizeof(DR_DEVICE_IOCOMPLETION));
1463
	      in_uint32_le(ls, rsp->Length);
1464
	      send_DR_DRIVE_SET_INFORMATION_RSP(rsp, u);
1465
	      s_mark_end(u);
1466
	      size = u->end - u->data;
1467
	      MDBGLOG("redir","INFO\t[%s()]: (RDPFS_FTRUNCATE) reply",__func__);
1468
	    }
1469
	    else if (rdp_opcode == RDPFS_END || rdp_opcode == RDPPORT_END) {
1470
	      MDBGLOG("redir","INFO\t[%s()]: (RDP_END) reply",__func__);
1471
	    }
1472
	    else if (rdp_opcode == RDPFS_DESTROY || rdp_opcode == RDPPORT_DESTROY) {
1473
	      MDBGLOG("redir","INFO\t[%s()]: (RDP_DESTROY) reply",__func__);
1474
	    }
1475
	    else {
1476
	      MDBGLOG("redir","ERROR\t[%s()]: unrecognized opcode \"0x%8.8x\"",__func__,rdp_opcode);
1477
	      suppress = 1;
1478
	    }
1479
1480
	    if (!suppress) {
1481
	      int devid = 0;
1482
	      struct trans * ccon = (struct trans *)NULL;
1483
	      devid = get_device_index(ioc.DeviceId);
1484
	      if (fhandle == 0) {
1485
		fhandle = g_callbacks[opid].FileId;
1486
	      }
1487
	      if (uniqid == 0) {
1488
		uniqid = g_callbacks[opid].uniqid;
1489
	      }
1490
	      TC_MUTEX_LOCK(mutex_client_devicelist);
1491
	      if (is_filesystem(devid)) {
1492
		MDBGLOG("redir","INFO\t[%s()]: is_filesystem() = true",__func__);
1493
		ccon = ((rdpfs *)(g_client_devicelist->DeviceList[devidx]->item))->ccon;
1494
	      }
1495
	      else if (is_port(devid)) {
1496
		MDBGLOG("redir","INFO\t[%s()]: is_port() = true",__func__);
1497
		ccon = ((rdpport_t *)(g_client_devicelist->DeviceList[devidx]->item))->ccon;
1498
	      }
1499
	      else if (is_printer(devid)) {
1500
		MDBGLOG("redir","INFO\t[%s()]: is_printer() = true",__func__);
1501
		ccon = ((rdpprint *)(g_client_devicelist->DeviceList[devidx]->item))->ccon;
1502
	      }
1503
	      else if (is_smartcard(devid)) {
1504
		MDBGLOG("redir","INFO\t[%s()]: is_smartcard() = true",__func__);
1505
		ccon = ((rdpsc *)(g_client_devicelist->DeviceList[devidx]->item))->ccon;
1506
	      }
1507
	      if (ccon != NULL) {
1508
		uint32_t * p_crc32 = (uint32_t *)NULL;
1509
		char * p = (char *)NULL;
1510
		magic = RDP_PACKET_MAGIC;
1511
		crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)(u->data), (size_t)(u->p - u->data));
1512
		t = trans_get_out_s(ccon, MAX_STREAM);
1513
		rdp_opcode |= RDP_REPLY;
1514
		if (device_id == 0) {
1515
		  device_id = ioc.DeviceId;
1516
		}
1517
		MDBGLOG("redir"," {} DeviceId = %d; device_id = %d; CompletionId = %d; IoStatus = 0x%8.8x; rdp_opcode = 0x%8.8x, fhandle = %d; uniqid = %d",ioc.DeviceId,device_id,ioc.CompletionId,ioc.IoStatus.Value,rdp_opcode,fhandle,uniqid);
1518
		out_uint32_le(t, magic);
1519
		out_uint32_le(t, rdp_opcode);
1520
		out_uint32_le(t, size);
1521
		out_uint32_le(t, device_id);
1522
		out_uint32_le(t, fhandle);
1523
		out_uint32_le(t, uniqid);
1524
		p_crc32 = (uint32_t *)s_get_pos(t);
1525
		out_uint32_le(t, crc32);
1526
		p = (char *)s_get_pos(t);
1527
		if (size > 0) {
1528
		  out_uint8a(t, u->data, size);
1529
		}
1530
		s_mark_end(t);
1531
		if (p_crc32 != NULL && p != NULL) {
1532
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(t->end - p));
1533
		}
1534
		MDBGLOG("redir","about to send reply...");
1535
		trans_force_write(ccon);
1536
		MDBGLOG("redir","reply sent. (size = %d)",size);
1537
		TC_MUTEX_UNLOCK(mutex_client_devicelist);
1538
	      }
1539
1540
	      if (send_partial < 1) {
1541
		g_memset(&(g_callbacks[opid]),0,sizeof(callback));
1542
	      }
1543
	    }
1544
	    TC_MUTEX_UNLOCK(mutex_cb);
1545
	  }
1546
	  break;
1547
	case PAKID_CORE_CLIENT_CAPABILITY:
1548
	  MDBGLOG("redir"," - hdr->PacketId = 0x%8.8x (PAKID_CORE_CLIENT_CAPABILITY)",hdr->PacketId);
1549
	  rv = rdpdr_process_CLIENT_CAPABILITY(ls);
1550
	  break;
1551
	case PAKID_CORE_DEVICELIST_REMOVE:
1552
	  MDBGLOG("redir"," - hdr->PacketId = 0x%8.8x (PAKID_CORE_DEVICELIST_REMOVE)",hdr->PacketId);
1553
	  rv = rdpdr_process_DEVICELIST_REMOVE(ls);
1554
	  break;
1555
        default:
1556
          MDBGLOG("redir", "\n !!! [%s()]: unknown hdr->PacketId[CORE] = 0x%8.8x\n", __func__, hdr->PacketId);
1557
          break;
1558
      }
1559
    }
1560
    else if (hdr->Component == RDPDR_CTYP_PRN) {
1561
      switch (hdr->PacketId) {
1562
	case PAKID_PRN_CACHE_DATA:
1563
	  MDBGLOG("redir"," - hdr->PacketId = 0x%8.8x (PAKID_PRN_CACHE_DATA)",hdr->PacketId);
1564
	  // rv = rdpdr_process_PRN_CACHE_DATA(ls);
1565
	  break;
1566
	case PAKID_PRN_USING_XPS:
1567
	  MDBGLOG("redir"," - hdr->PacketId = 0x%8.8x (PAKID_PRN_USING_XPS)",hdr->PacketId);
1568
	  // rv = rdpdr_process_PRN_USING_XPS(ls);
1569
	  break;
1570
        default:
1571
          MDBGLOG("redir", "\n !!! INFO\t[%s()]: unknown hdr->PacketId[PRN] = 0x%8.8x\n", __func__, hdr->PacketId);
1572
          break;
1573
      }
1574
    }
1575
1576
  }
1577
1578
  return rv;
46
}
1579
}
47
1580
48
/*****************************************************************************/
1581
/*****************************************************************************/
49
int APP_CC
1582
int APP_CC
50
dev_redir_get_wait_objs(tbus* objs, int* count, int* timeout)
1583
rdpdr_get_wait_objs(tbus * objs, int * count, int * timeout) {
51
{
1584
  int rv = 0;
52
  return 0;
1585
  int lcount = 0;
1586
  int idx = 0;
1587
1588
  // MDBGLOG("redir","INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
1589
1590
  if ((g_rdpdr_up == 0) || (objs == 0) || (count == 0) || g_is_child > 0)
1591
  {
1592
  }
1593
  else if (g_rdpdr_wait_obj > -1) {
1594
    lcount = *count;
1595
    objs[lcount] = g_rdpdr_wait_obj;
1596
    lcount++;
1597
    *count = lcount;
1598
    TC_MUTEX_LOCK(mutex_client_devicelist);
1599
    if (g_client_devicelist != NULL && g_client_devicelist->DeviceCount > 0)
1600
    for (idx=0; idx < g_client_devicelist->DeviceCount; idx++) {
1601
      if (g_client_devicelist->DeviceList[idx] != NULL && g_client_devicelist->DeviceList[idx]->item != NULL) {
1602
	int sck = -1;
1603
	if (is_filesystem(idx) && ((rdpfs *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpfs *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1604
	  sck = ((rdpfs *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck;
1605
	  // MDBGLOG("redir","INFO\t[%s()]: filesystem (sck = %d)",__func__,sck);
1606
	}
1607
	else if (is_port(idx) && ((rdpport_t *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpport_t *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1608
	  sck = ((rdpport_t *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck;
1609
	  // MDBGLOG("redir","INFO\t[%s()]: port (sck = %d)",__func__,sck);
1610
	}
1611
	else if (is_printer(idx) && ((rdpprint *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpprint *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1612
	  sck = ((rdpprint *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck;
1613
	  // MDBGLOG("redir","INFO\t[%s()]: printer (sck = %d)",__func__,sck);
1614
	}
1615
	else if (is_smartcard(idx) && ((rdpsc *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpsc *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1616
	  sck = ((rdpsc *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck;
1617
	  // MDBGLOG("redir","INFO\t[%s()]: smartcard (sck = %d)",__func__,sck);
1618
	}
1619
	else {
1620
	  // MDBGLOG("redir","ERROR\t[%s()]: unrecognized origin",__func__);
1621
	}
1622
	if (sck > 0) {
1623
	  lcount = *count;
1624
	  objs[lcount] = sck;
1625
	  lcount++;
1626
	  *count = lcount;
1627
	}
1628
      }
1629
    }
1630
    TC_MUTEX_UNLOCK(mutex_client_devicelist);
1631
  }
1632
1633
  // MDBGLOG("redir","INFO\t[%s()]: done (lcount = %d).", __func__, lcount);
1634
  return rv;
53
}
1635
}
54
1636
55
/*****************************************************************************/
1637
/*****************************************************************************/
56
int APP_CC
1638
int APP_CC
57
dev_redir_check_wait_objs(void)
1639
rdpdr_check_wait_objs(void) {
58
{
1640
  int rv = 0;
59
  return 0;
1641
  int idx = 0;
1642
1643
  //MDBGLOG("redir","INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
1644
1645
  if (!g_rdpdr_up || g_is_child > 0) {
1646
    rv = 0;
1647
  }
1648
  else {
1649
    TC_MUTEX_LOCK(mutex_client_devicelist);
1650
    if (g_is_wait_obj_set(g_rdpdr_wait_obj)) {
1651
      // MDBGLOG("redir","INFO\t[%s()]: g_rdpdr_wait_obj = %d [SET]",__func__,g_rdpdr_wait_obj);
1652
    }
1653
    else if (g_client_devicelist != NULL && g_client_devicelist->DeviceCount > 0)
1654
      for (idx = 0; idx < g_client_devicelist->DeviceCount; idx++) {
1655
      if (g_client_devicelist->DeviceList[idx] == NULL || g_client_devicelist->DeviceList[idx]->item == NULL) {
1656
	// MDBGLOG("redir","ERROR\t[%s()]: NULL pointer (idx = %d)",__func__,idx);
1657
      }
1658
      else {
1659
	struct trans * ccon = (struct trans *)NULL;
1660
	if (is_filesystem(idx) && ((rdpfs *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpfs *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1661
	  // MDBGLOG("redir","INFO\t[%s()]: setting ccon for filesystem (idx = %d)",__func__,idx);
1662
	  ccon = ((rdpfs *)(g_client_devicelist->DeviceList[idx]->item))->ccon;
1663
	}
1664
	else if (is_port(idx) && ((rdpport_t *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpport_t *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1665
	  // MDBGLOG("redir","INFO\t[%s()]: setting ccon for port (idx = %d)",__func__,idx);
1666
	  ccon = ((rdpport_t *)(g_client_devicelist->DeviceList[idx]->item))->ccon;
1667
	}
1668
	else if (is_printer(idx) && ((rdpprint *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpprint *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1669
	  // MDBGLOG("redir","INFO\t[%s()]: setting ccon for printer",__func__);
1670
	  ccon = ((rdpprint *)(g_client_devicelist->DeviceList[idx]->item))->ccon;
1671
	}
1672
	else if (is_smartcard(idx) && ((rdpsc *)(g_client_devicelist->DeviceList[idx]->item))->ccon != NULL && ((rdpsc *)(g_client_devicelist->DeviceList[idx]->item))->ccon->sck > 0) {
1673
	  // MDBGLOG("redir","INFO\t[%s()]: setting ccon for smartcard",__func__);
1674
	  ccon = ((rdpsc *)(g_client_devicelist->DeviceList[idx]->item))->ccon;
1675
	}
1676
	else {
1677
	  // MDBGLOG("redir","ERROR\t[%s()]: unrecognized origin",__func__);
1678
	}
1679
	/* handle any inbound replies from the child: */
1680
	if (ccon != NULL && trans_check_wait_objs(ccon) != 0) {
1681
	  // MDBGLOG("redir","ERROR\t[%s()]: trans_check_wait_objs(ccon) != 0",__func__);
1682
	  rv = -1;
1683
	}
1684
      }
1685
    }
1686
    TC_MUTEX_UNLOCK(mutex_client_devicelist);
1687
  }
1688
  // MDBGLOG("redir","INFO\t[%s()]: done (rv = %d).", __func__, rv);
1689
  return rv;
1690
}
1691
1692
/*****************************************************************************/
1693
static int APP_CC
1694
rdpdr_process_format_announce(struct stream * ls, int a, int b) {
1695
  int rv = 0;
1696
  return rv;
1697
}
1698
1699
/*****************************************************************************/
1700
static int APP_CC
1701
rdpdr_process_format_ack(struct stream * ls, int a, int b) {
1702
  int rv = 0;
1703
  return rv;
1704
}
1705
1706
/*****************************************************************************/
1707
static int APP_CC
1708
rdpdr_process_data_request(struct stream * ls, int a, int b) {
1709
  int rv = 0;
1710
  return rv;
1711
}
1712
1713
/*****************************************************************************/
1714
static int APP_CC
1715
rdpdr_process_data_response(struct stream * ls, int a, int b) {
1716
  int rv = 0;
1717
  return rv;
1718
}
1719
1720
/*****************************************************************************/
1721
static int APP_CC
1722
rdpdr_process_DEVICE_REPLY(struct stream * s) {
1723
  int rv = 0;
1724
  MDBGLOG("redir","DEVICE_REPLY");
1725
  return rv;
1726
}
1727
1728
/*****************************************************************************/
1729
static int APP_CC
1730
rdpdr_process_DEVICE_IOREQUEST(struct stream * s) {
1731
  int rv = 0;
1732
  DR_DEVICE_IOREQUEST * pdu = (DR_DEVICE_IOREQUEST *)NULL;
1733
1734
  MDBGLOG("redir","DEVICE_IOREQUEST");
1735
1736
  pdu = RDPDR_NEW(DR_DEVICE_IOREQUEST);
1737
  pdu->in(pdu, s);
1738
1739
  return rv;
1740
}
1741
1742
/*****************************************************************************/
1743
static int APP_CC
1744
rdpdr_process_SERVER_CAPABILITY(struct stream * s) {
1745
  int rv = 0;
1746
  MDBGLOG("redir","SERVER_CAPABILITY");
1747
  return rv;
1748
}
1749
1750
/*****************************************************************************/
1751
static int APP_CC
1752
rdpdr_process_CLIENT_CAPABILITY(struct stream * s) {
1753
  int rv = 0;
1754
  MDBGLOG("redir","CLIENT_CAPABILITY");
1755
  return rv;
1756
}
1757
1758
/*****************************************************************************/
1759
static int APP_CC
1760
rdpdr_process_DEVICELIST_REMOVE(struct stream * s) {
1761
  int rv = 0;
1762
  MDBGLOG("redir","DEVICELIST_REMOVE");
1763
  return rv;
1764
}
1765
1766
/*************************************************************************/
1767
/*************************************************************************/
1768
1769
1770
/****************
1771
   send / receive
1772
 ****************/
1773
1774
/****************
1775
   destructors
1776
 ****************/
1777
1778
/*****************************************************************************/
1779
static int APP_CC
1780
rdpdr_process_DEVICELIST_ANNOUNCE(struct stream * s) {
1781
  int rv = 0;
1782
  int idx = 0;
1783
  int largc = 0;
1784
  int tmp = 0;
1785
  int tpos = 0;
1786
  int l_client_device_id = 0;
1787
  int child_finish = 0;
1788
  int l_fs = 0;
1789
  int l_port = 0;
1790
  int l_print = 0;
1791
  int l_sc = 0;
1792
  int g_pv[2] = { -1, -1 };
1793
  int g_sv[2] = { -1, -1 };
1794
  char ** largv = (char **)NULL;
1795
  char fname[512];
1796
1797
  MDBGLOG("redir","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
1798
1799
  g_memset(fname, 0, sizeof(char) * 512);
1800
  TC_MUTEX_LOCK(mutex_client_devicelist);
1801
  if (g_client_devicelist == NULL) {
1802
    g_client_devicelist = RDPDR_NEW(DR_DEVICELIST_ANNOUNCE);
1803
  }
1804
  if (g_client_devicelist->DeviceList == NULL) {
1805
    g_client_devicelist->DeviceList = (DEVICE_ANNOUNCE **)g_malloc(sizeof(size_t) * 96, 1);
1806
  }
1807
  TC_MUTEX_LOCK(mutex_fs_arr);
1808
  l_fs = 1;
1809
  if (g_fs_arr == NULL) {
1810
    g_fs_arr = (rdpfs **)g_malloc(sizeof(size_t) * 24, 1);
1811
  }
1812
  TC_MUTEX_LOCK(mutex_port_arr);
1813
  l_port = 1;
1814
  if (g_port_arr == NULL) {
1815
    g_port_arr = (rdpport_t **)g_malloc(sizeof(size_t) * 24, 1);
1816
  }
1817
  TC_MUTEX_LOCK(mutex_printer_arr);
1818
  l_print = 1;
1819
  if (g_printer_arr == NULL) {
1820
    g_printer_arr = (rdpprint **)g_malloc(sizeof(size_t) * 24, 1);
1821
  }
1822
  TC_MUTEX_LOCK(mutex_smartcard_arr);
1823
  l_sc = 1;
1824
  if (g_smartcard_arr == NULL) {
1825
    g_smartcard_arr = (rdpsc **)g_malloc(sizeof(size_t) * 24, 1);
1826
  }
1827
  in_uint32_le(s, tmp);
1828
/*** !!!!! ugly development hack !!!! ***/
1829
  //tmp = 1;
1830
  g_client_devicelist->DeviceCount += tmp;
1831
  for (idx = 0; idx < tmp; idx++) {
1832
//    tpos = g_client_devicelist->DeviceCount + idx;
1833
//    tpos = (g_client_devicelist->DeviceCount > 0) ? (g_client_devicelist->DeviceCount - 1) + idx : idx;
1834
    tpos = idx;
1835
    g_client_devicelist->DeviceList[tpos] = RDPDR_NEW(DEVICE_ANNOUNCE);
1836
    in_uint32_le(s, g_client_devicelist->DeviceList[tpos]->DeviceType);
1837
    in_uint32_le(s, g_client_devicelist->DeviceList[tpos]->DeviceId);
1838
    l_client_device_id = g_client_devicelist->DeviceList[tpos]->DeviceId;
1839
    in_uint8a(s, g_client_devicelist->DeviceList[tpos]->PreferredDosName, 8);
1840
    in_uint32_le(s, g_client_devicelist->DeviceList[tpos]->DeviceDataLength);
1841
    if (g_client_devicelist->DeviceList[tpos]->DeviceDataLength > 0) {
1842
      g_client_devicelist->DeviceList[tpos]->DeviceData = (BYTE *)g_malloc(sizeof(BYTE) * g_client_devicelist->DeviceList[tpos]->DeviceDataLength, 1);
1843
      in_uint8a(s, g_client_devicelist->DeviceList[tpos]->DeviceData, g_client_devicelist->DeviceList[tpos]->DeviceDataLength);
1844
    }
1845
  }
1846
  for (idx = 0; idx < tmp; idx++) {
1847
    MDBGLOG("redir","\n\t[[ DeviceDataLength = %d ]]\n",g_client_devicelist->DeviceList[tpos]->DeviceDataLength);
1848
1849
    tpos = idx;
1850
    l_client_device_id = g_client_devicelist->DeviceList[tpos]->DeviceId;
1851
1852
    /* if the device is a serial port, then handle it: */
1853
    if ((g_client_devicelist->DeviceList[tpos]->DeviceType & RDPDR_DTYP_SERIAL) == g_client_devicelist->DeviceList[tpos]->DeviceType) {
1854
      char dbuf[512];
1855
      char * dos_name = (char *)NULL;
1856
      g_memset(dbuf,0,sizeof(dbuf));
1857
      dos_name = (g_client_devicelist->DeviceList[tpos]->PreferredDosName == NULL) ? g_strdup("NONE") : g_strdup(g_client_devicelist->DeviceList[tpos]->PreferredDosName);
1858
      g_port_arr[g_port_count] = (rdpport_t *)rdpport_main(SERIAL_PORT,g_port_count);
1859
      g_client_devicelist->DeviceList[tpos]->item = g_port_arr[g_port_count];
1860
      if (g_port_arr[g_port_count] == NULL) {
1861
	continue;
1862
      }
1863
      g_port_arr[g_port_count]->device_id = g_client_devicelist->DeviceList[tpos]->DeviceId;
1864
      g_port_arr[g_port_count]->g_port_index = g_port_count;
1865
      g_port_arr[g_port_count]->g_device_index = tpos;
1866
      g_socketpair(g_pv);
1867
      g_tcp_set_non_blocking(g_pv[0]);
1868
      g_tcp_set_non_blocking(g_pv[1]);
1869
      g_port_arr[g_port_count]->parent_sck = g_pv[0];
1870
      g_port_arr[g_port_count]->child_sck = g_pv[1];
1871
      g_port_arr[g_port_count]->parent_pid = g_getpid();
1872
      g_port_arr[g_port_count]->dos_name = dos_name;
1873
      g_port_count++;
1874
      MDBGLOG("redir"," ** serial port: \"%s\" (DeviceId = %d)",dos_name,l_client_device_id);
1875
    }
1876
    /* if the device is a parallel port, then handle it: */
1877
    else if ((g_client_devicelist->DeviceList[tpos]->DeviceType & RDPDR_DTYP_PARALLEL) == RDPDR_DTYP_PARALLEL) {
1878
      char * dos_name = (char *)NULL;
1879
      dos_name = (g_client_devicelist->DeviceList[tpos]->PreferredDosName == NULL) ? g_strdup("NONE") : g_strdup(g_client_devicelist->DeviceList[tpos]->PreferredDosName);
1880
      g_port_arr[g_port_count] = (rdpport_t *)rdpport_main(PARALLEL_PORT,g_port_count);
1881
      g_client_devicelist->DeviceList[tpos]->item = g_port_arr[g_port_count];
1882
      if (g_port_arr[g_port_count] == NULL) {
1883
	continue;
1884
      }
1885
      g_port_arr[g_port_count]->device_id = g_client_devicelist->DeviceList[tpos]->DeviceId;
1886
      g_port_arr[g_port_count]->g_port_index = g_port_count;
1887
      g_port_arr[g_port_count]->g_device_index = tpos;
1888
      g_socketpair(g_pv);
1889
      g_tcp_set_non_blocking(g_pv[0]);
1890
      g_tcp_set_non_blocking(g_pv[1]);
1891
      g_port_arr[g_port_count]->parent_sck = g_pv[0];
1892
      g_port_arr[g_port_count]->child_sck = g_pv[1];
1893
      g_port_arr[g_port_count]->parent_pid = g_getpid();
1894
      l_child_pid = g_fork();
1895
      if (l_child_pid == 0) {	/* child process */
1896
	l_child_pid = g_getpid();
1897
	g_port_arr[g_port_count]->handler_pid = l_child_pid;
1898
	if (l_port > 0) {
1899
	  TC_MUTEX_UNLOCK(mutex_port_arr);
1900
	  l_port = 0;
1901
	}
1902
	handle_port(g_pv[1], g_port_arr[g_port_count]);
1903
      }
1904
      else {		/* parent process */
1905
	g_port_arr[g_port_count]->handler_pid = l_child_pid;
1906
	//g_tcp_close(g_port_arr[g_port_count]->fd);
1907
1908
	/* set up ccon as a transmission channel to the child */
1909
	g_port_arr[g_port_count]->ccon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
1910
	g_port_arr[g_port_count]->ccon->trans_data_in = &port_data_in;
1911
	g_port_arr[g_port_count]->ccon->header_size = 28;
1912
	trans_attach(g_port_arr[g_port_count]->ccon, g_port_arr[g_port_count]->parent_sck);
1913
	g_port_arr[g_port_count]->ccon->sck = g_port_arr[g_port_count]->parent_sck;
1914
	g_port_arr[g_port_count]->ccon->callback_data = (rdpport_t *)(g_port_arr[g_port_count]);
1915
	MDBGLOG("redir"," --> g_pv[0] = %d", g_pv[0]);
1916
      }
1917
      g_port_count++;
1918
      MDBGLOG("redir"," ** parallel port: \"%s\" (DeviceId = %d)",dos_name,l_client_device_id);
1919
    }
1920
    /* if the device is a printer, then create a corresponding rdpprint and manage it: */
1921
    else if ((g_client_devicelist->DeviceList[tpos]->DeviceType & RDPDR_DTYP_PRINT) == RDPDR_DTYP_PRINT) {
1922
      char * dos_name = (char *)NULL;
1923
      dos_name = g_strdup(g_client_devicelist->DeviceList[tpos]->PreferredDosName);
1924
      g_printer_arr[g_printer_count] = (rdpprint *)g_malloc(sizeof(rdpprint), 1);
1925
      g_client_devicelist->DeviceList[tpos]->item = g_printer_arr[g_printer_count];
1926
      if (g_printer_arr[g_printer_count] == NULL) {
1927
	continue;
1928
      }
1929
      g_printer_arr[g_printer_count]->type = XPS_PRINTER;
1930
      g_printer_arr[g_printer_count]->device_id = g_client_devicelist->DeviceList[tpos]->DeviceId;
1931
      g_printer_arr[g_printer_count]->g_printer_index = tpos;
1932
      g_socketpair(g_pv);
1933
      g_tcp_set_non_blocking(g_pv[0]);
1934
      g_tcp_set_non_blocking(g_pv[1]);
1935
      g_printer_arr[g_printer_count]->parent_sck = g_pv[0];
1936
      g_printer_arr[g_printer_count]->child_sck = g_pv[1];
1937
      g_printer_arr[g_printer_count]->parent_pid = g_getpid();
1938
      p_child_pid = g_fork();
1939
      if (p_child_pid == 0) {	/* child process */
1940
	p_child_pid = g_getpid();
1941
	g_printer_arr[g_printer_count]->handler_pid = p_child_pid;
1942
	if (l_print > 0) {
1943
	  TC_MUTEX_UNLOCK(mutex_printer_arr);
1944
	  l_print = 0;
1945
	}
1946
	handle_printer(g_pv[1], g_printer_arr[g_printer_count]);
1947
      }
1948
      else {		/* parent process */
1949
	g_printer_arr[g_printer_count]->handler_pid = p_child_pid;
1950
	//g_tcp_close(g_printer_arr[g_printer_count]->fd);
1951
1952
	/* set up ccon as a transmission channel to the child */
1953
	g_printer_arr[g_printer_count]->ccon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
1954
	g_printer_arr[g_printer_count]->ccon->trans_data_in = &printer_data_in;
1955
	g_printer_arr[g_printer_count]->ccon->header_size = 28;
1956
	trans_attach(g_printer_arr[g_printer_count]->ccon, g_printer_arr[g_printer_count]->parent_sck);
1957
	g_printer_arr[g_printer_count]->ccon->sck = g_printer_arr[g_printer_count]->parent_sck;
1958
	g_printer_arr[g_printer_count]->ccon->callback_data = (rdpprint *)(g_printer_arr[g_printer_count]);
1959
	MDBGLOG("redir"," --> g_pv[0] = %d", g_pv[0]);
1960
      }
1961
      g_printer_count++;
1962
      MDBGLOG("redir"," ** printer: \"%s\" (DeviceId = %d)",dos_name,l_client_device_id);
1963
    }
1964
    /* if the device is a smartcard, then create a corresponding rdpsc and manage it: */
1965
    else if ((g_client_devicelist->DeviceList[tpos]->DeviceType & RDPDR_DTYP_SMARTCARD) == RDPDR_DTYP_SMARTCARD) {
1966
      char * dos_name = (char *)NULL;
1967
      dos_name = g_strdup(g_client_devicelist->DeviceList[g_smartcard_count]->PreferredDosName);
1968
      g_smartcard_arr[g_smartcard_count] = (rdpsc *)g_malloc(sizeof(rdpsc), 1);
1969
      g_client_devicelist->DeviceList[tpos]->item = g_smartcard_arr[g_smartcard_count];
1970
      if (g_smartcard_arr[g_smartcard_count] == NULL) {
1971
	continue;
1972
      }
1973
      g_smartcard_arr[g_smartcard_count]->device_id = g_client_devicelist->DeviceList[tpos]->DeviceId;
1974
      g_smartcard_arr[g_smartcard_count]->g_smartcard_index = g_smartcard_count;
1975
      g_smartcard_arr[g_smartcard_count]->g_device_index = tpos;
1976
      g_socketpair(g_pv);
1977
      g_tcp_set_non_blocking(g_pv[0]);
1978
      g_tcp_set_non_blocking(g_pv[1]);
1979
      g_smartcard_arr[g_smartcard_count]->parent_sck = g_pv[0];
1980
      g_smartcard_arr[g_smartcard_count]->child_sck = g_pv[1];
1981
      g_smartcard_arr[g_smartcard_count]->parent_pid = g_getpid();
1982
      s_child_pid = g_fork();
1983
      if (s_child_pid == 0) {	/* child process */
1984
	s_child_pid = g_getpid();
1985
	g_smartcard_arr[g_smartcard_count]->handler_pid = s_child_pid;
1986
	if (l_sc > 0) {
1987
	  TC_MUTEX_UNLOCK(mutex_smartcard_arr);
1988
	  l_sc = 0;
1989
	}
1990
	handle_smartcard(g_pv[1], g_smartcard_arr[g_smartcard_count]);
1991
      }
1992
      else {		/* parent process */
1993
	g_smartcard_arr[g_smartcard_count]->handler_pid = s_child_pid;
1994
1995
	//g_tcp_close(g_smartcard_arr[g_smartcard_count]->fd);
1996
1997
	/* set up ccon as a transmission channel to the child */
1998
	g_smartcard_arr[g_smartcard_count]->ccon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
1999
	g_smartcard_arr[g_smartcard_count]->ccon->trans_data_in = &smartcard_data_in;
2000
	g_smartcard_arr[g_smartcard_count]->ccon->header_size = 28;
2001
	trans_attach(g_smartcard_arr[g_smartcard_count]->ccon, g_smartcard_arr[g_smartcard_count]->parent_sck);
2002
	g_smartcard_arr[g_smartcard_count]->ccon->sck = g_smartcard_arr[g_smartcard_count]->parent_sck;
2003
	g_smartcard_arr[g_smartcard_count]->ccon->callback_data = (rdpsc *)(g_smartcard_arr[g_smartcard_count]);
2004
	MDBGLOG("redir"," --> g_pv[0] = %d", g_pv[0]);
2005
      }
2006
    }
2007
    /* if the device is a file system, then create a corresponding rdpfs and mount it: */
2008
    else if ((g_client_devicelist->DeviceList[tpos]->DeviceType & RDPDR_DTYP_FILESYSTEM) == RDPDR_DTYP_FILESYSTEM) {
2009
      char * dos_name = (char *)NULL;
2010
      char * ncolon = (char *)NULL;
2011
      dos_name = g_client_devicelist->DeviceList[tpos]->PreferredDosName;
2012
      ncolon = g_strchr(g_client_devicelist->DeviceList[tpos]->PreferredDosName,':');
2013
      if (ncolon != NULL) {
2014
	int tnum = 0;
2015
	tnum = (char *)ncolon - (char *)(g_client_devicelist->DeviceList[tpos]->PreferredDosName);
2016
	dos_name = (char *)g_malloc(sizeof(char)*tnum, 1);
2017
	g_strncpy(dos_name,g_client_devicelist->DeviceList[tpos]->PreferredDosName,tnum);
2018
      }
2019
      if (!g_directory_exist(g_fbase)) {
2020
	if (!g_directory_exist("/media")) {
2021
	  MDBGLOG("parent","ERROR [rdpdr_process_DEVICELIST_ANNOUNCE()]: mount directory \"/media\" does not exist; not mounting remote filesystem");
2022
	}
2023
	else {
2024
	  g_dir_create(g_fbase,0755);
2025
	}
2026
      }
2027
      g_snprintf(fname,511,"%s/%s",g_fbase,dos_name);
2028
      largc = 1;
2029
      largv = (char **)g_malloc(sizeof(size_t) * largc, 1);
2030
      largv[0] = g_strdup(fname);
2031
      largv[1] = (char *)NULL;
2032
      MDBGLOG("redir","largc = %d; largv[0] = %s; largv[1] = %s",largc,largv[0],largv[1]);
2033
2034
      g_fs_arr[g_fs_count] = (rdpfs *)rdpfs_main(largc, largv, largv[0]);
2035
      g_client_devicelist->DeviceList[tpos]->item = g_fs_arr[g_fs_count];
2036
      if (g_fs_arr[g_fs_count] == NULL) {
2037
	//TC_MUTEX_UNLOCK(g_handle_fs_mut);
2038
	continue;
2039
      }
2040
      g_fs_arr[g_fs_count]->g_fs_index = g_fs_count;
2041
      g_memset(fname, 0, sizeof(char) * 512);
2042
      if (largv[0] != NULL) {
2043
	//g_free(largv[0]);
2044
      }
2045
      if (largv != NULL) {
2046
	//g_free(largv);
2047
      }
2048
2049
      g_fs_arr[g_fs_count]->device_id = g_client_devicelist->DeviceList[tpos]->DeviceId;
2050
      g_fs_arr[g_fs_count]->g_fs_index = g_fs_count;
2051
      g_fs_arr[g_fs_count]->g_device_index = tpos;
2052
      g_socketpair(g_pv);
2053
      g_tcp_set_non_blocking(g_pv[0]);
2054
      g_tcp_set_non_blocking(g_pv[1]);
2055
      g_fs_arr[g_fs_count]->parent_sck = g_pv[0];
2056
      g_fs_arr[g_fs_count]->child_sck = g_pv[1];
2057
      g_fs_arr[g_fs_count]->parent_pid = g_getpid();
2058
      g_fs_count++;
2059
      //MDBGLOG("redir","INFO\t[%s()]:  ** file system: \"%s\" (DeviceId = %d, l_client_device_id = %d)",__func__,dos_name,g_fs_arr[g_fs_count]->device_id,l_client_device_id);
2060
    }
2061
  }
2062
2063
  if (l_sc > 0) {
2064
    TC_MUTEX_UNLOCK(mutex_smartcard_arr);
2065
    l_sc = 0;
2066
  }
2067
  if (l_print > 0) {
2068
    TC_MUTEX_UNLOCK(mutex_printer_arr);
2069
    l_print = 0;
2070
  }
2071
2072
  for (idx = 0; idx < g_port_count; idx++) {
2073
      int l_port_count = idx;
2074
      l_child_pid = g_fork();
2075
      if (l_child_pid == 0) {	/* child process */
2076
	g_is_child = 1;
2077
	l_child_pid = g_getpid();
2078
	g_port_arr[l_port_count]->handler_pid = l_child_pid;
2079
	g_port_arr[l_port_count]->child_pid = l_child_pid;
2080
	//g_tcp_close(g_port_arr[l_port_count]->child_sck);
2081
	if (l_port > 0) {
2082
	  TC_MUTEX_UNLOCK(mutex_port_arr);
2083
	  l_port = 0;
2084
	}
2085
	handle_port(g_port_arr[l_port_count]->child_sck, g_port_arr[l_port_count]);
2086
      }
2087
      else {		/* parent process */
2088
	g_port_arr[l_port_count]->handler_pid = l_child_pid;
2089
	g_port_arr[l_port_count]->child_pid = l_child_pid;
2090
	//g_tcp_close(g_port_arr[l_port_count]->parent_sck);
2091
2092
	/* set up ccon as a transmission channel to the child */
2093
	g_port_arr[l_port_count]->ccon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
2094
	g_port_arr[l_port_count]->ccon->trans_data_in = &port_data_in;
2095
	g_port_arr[l_port_count]->ccon->header_size = 28;
2096
	trans_attach(g_port_arr[l_port_count]->ccon, g_port_arr[l_port_count]->parent_sck);
2097
	g_port_arr[l_port_count]->ccon->sck = g_port_arr[l_port_count]->parent_sck;
2098
	g_port_arr[l_port_count]->ccon->callback_data = (rdpport_t *)(g_port_arr[l_port_count]);
2099
	//MDBGLOG("redir"," --> g_pv[0] = %d", g_pv[0]);
2100
	MDBGLOG("redir","INFO\t[%s()]: --> g_port_arr[l_port_count]->ccon->sck = %d", __func__, g_port_arr[l_port_count]->ccon->sck);
2101
      }
2102
  }
2103
2104
  if (l_port > 0) {
2105
    TC_MUTEX_UNLOCK(mutex_port_arr);
2106
    l_port = 0;
2107
  }
2108
2109
  MDBGLOG("redir","INFO\t[%s()]: about to lock <g_handle_fs_mut>... [%d, %d]",__func__,g_getpid(),g_gettid());
2110
  //TC_MUTEX_LOCK(g_handle_fs_mut);
2111
  for (idx = 0; idx < g_fs_count; idx++) {
2112
      int l_fs_count = idx;
2113
      l_child_pid = g_fork();
2114
      if (l_child_pid == 0) {	// child process
2115
	MDBGLOG("redir","INFO\t[%s()]: idx = %d [%d, %d]",__func__,idx,g_getpid(),g_gettid());
2116
	g_is_child = 1;
2117
	break;
2118
      }
2119
      else {			// parent process
2120
	MDBGLOG("redir","INFO\t[%s()]: idx = %d [%d, %d]",__func__,idx,g_getpid(),g_gettid());
2121
	/* set up ccon as a transmission channel to the child */
2122
	g_fs_arr[l_fs_count]->handler_pid = l_child_pid;
2123
	g_fs_arr[l_fs_count]->child_pid = l_child_pid;
2124
      }
2125
  }
2126
  if (g_is_child > 0) {
2127
      int l_fs_count = idx;
2128
      if (g_is_child > 0) {
2129
	int j = 0;
2130
	l_child_pid = g_getpid();
2131
	g_fs_arr[l_fs_count]->handler_pid = l_child_pid;
2132
	g_fs_arr[l_fs_count]->child_pid = l_child_pid;
2133
	MDBGLOG("redir", "INFO\t[%s()]: child process (filesystem: parent_pid = %d, parent_sck = %d, child_pid = %d, child_sck = %d)", __func__, g_fs_arr[l_fs_count]->parent_pid, g_fs_arr[l_fs_count]->parent_sck, g_fs_arr[l_fs_count]->child_pid, g_fs_arr[l_fs_count]->child_sck);
2134
//	for (j = 0; j < l_fs_count; j++) {
2135
	for (j = 0; j < g_fs_count; j++) if (g_fs_arr[j] != NULL) {
2136
	  if (g_fs_arr[j]->ccon != NULL && g_fs_arr[j]->ccon->sck) {
2137
	    //g_file_close(g_fs_arr[j]->ccon->sck);
2138
	  }
2139
	  //g_fs_arr[j]->initialized = 0;
2140
	  trans_detach(g_fs_arr[j]->ccon);
2141
	  //trans_delete(g_fs_arr[j]->ccon);
2142
	  if (g_fs_arr[j] != NULL && g_fs_arr[j]->ccon != NULL) {
2143
	    //g_free(g_fs_arr[j]->ccon);
2144
	    //g_fs_arr[j]->ccon = NULL;
2145
	  }
2146
	}
2147
	{
2148
	  int tsck = g_fs_arr[l_fs_count]->child_sck;
2149
	  rdpfs * tfs = g_fs_arr[l_fs_count];
2150
	  rdpfs ** tfs_arr = g_fs_arr;
2151
	  tc_p pmut = mutex_fs_arr;
2152
	  if (l_fs > 0) {
2153
	    TC_MUTEX_UNLOCK(mutex_fs_arr);
2154
	    l_fs = 0;
2155
	  }
2156
	  handle_filesystem(tsck, tfs, tfs_arr, pmut);
2157
	}
2158
	child_finish = 1;
2159
	//break;
2160
	//goto finish;
2161
      }
2162
      else {		/* parent process */
2163
      }
2164
  }
2165
  else {
2166
    for (idx = 0; idx < g_fs_count; idx++) {
2167
	int l_fs_count = idx;
2168
	MDBGLOG("redir","INFO\t[%s()]: (round2) idx = %d [%d, %d]",__func__,idx,g_getpid(),g_gettid());
2169
	g_fs_arr[l_fs_count]->ccon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
2170
	g_fs_arr[l_fs_count]->ccon->trans_data_in = &filesystem_data_in;
2171
	g_fs_arr[l_fs_count]->ccon->header_size = 28;
2172
	trans_attach(g_fs_arr[l_fs_count]->ccon, g_fs_arr[l_fs_count]->parent_sck);
2173
	g_fs_arr[l_fs_count]->ccon->sck = g_fs_arr[l_fs_count]->parent_sck;
2174
	g_fs_arr[l_fs_count]->ccon->callback_data = (rdpfs *)(g_fs_arr[l_fs_count]);
2175
    }
2176
  }
2177
  if (g_fs_count > 0 && child_finish < 1) {
2178
    g_handle_filesystem_called = 1;
2179
  }
2180
  if (child_finish < 1) {
2181
    //TC_MUTEX_UNLOCK(g_handle_fs_mut);
2182
  }
2183
2184
  if (l_fs > 0) {
2185
    TC_MUTEX_UNLOCK(mutex_fs_arr);
2186
    l_fs = 0;
2187
  }
2188
2189
  TC_MUTEX_UNLOCK(mutex_client_devicelist);
2190
2191
  //MDBGLOG("redir","rdpdr_process_DEVICELIST_ANNOUNCE(): done (DeviceType = 0x%8.8x; DeviceId = 0x%8.8x; PreferredDosName = %s).",g_client_devicelist->DeviceList[tpos]->DeviceType,g_client_devicelist->DeviceList[tpos]->DeviceId,g_client_devicelist->DeviceList[tpos]->PreferredDosName);
2192
  return rv;
2193
}
2194
2195
2196
/*****************************************************************************/
2197
static char * APP_CC ucs2ascii(const uint8_t * ucs) {
2198
  char * ascii = NULL;
2199
  char el = -1;
2200
  int idx = 0;
2201
2202
  ascii = g_malloc(sizeof(char)*512,1);
2203
  for (idx = 0; (idx < 511) && (el != 0); idx++) {
2204
    el = ucs[(idx * 2)];
2205
    ascii[idx] = el;
2206
  }
2207
2208
  return ascii;
2209
}
2210
2211
/*****************************************************************************/
2212
static int APP_CC
2213
port_data_in(struct trans * trans) {
2214
  int rv = 0;
2215
  struct stream * s = (struct stream *)NULL;
2216
  char odata[MAX_STREAM];
2217
  struct stream os;
2218
  char qdata[MAX_STREAM];
2219
  struct stream qs;
2220
  char tdata[MAX_STREAM];
2221
  struct stream ts;
2222
  struct stream * r = (struct stream *)NULL;
2223
  struct stream * q = (struct stream *)NULL;
2224
  struct stream * l = (struct stream *)NULL;
2225
  callback * cb = (callback *)NULL;
2226
  int fpath_length = 0;
2227
  int rdpport_opcode = 0;
2228
  int size = 0;
2229
  int error = 0;
2230
  int idx = 0;
2231
  int opid = 0;
2232
  int fhandle = 0;
2233
  int uniqid = 0;
2234
  uint32_t tflags = 0x00000000;
2235
  uint32_t toptions = 0x00000000;
2236
  uint32_t tshare = 0x00000000;
2237
  uint32_t tsize = 0x00000000;
2238
  uint64_t toffset = 0x0000000000000000;
2239
  uint64_t tchangetime = 0x0000000000000000;
2240
  uint64_t tactime = 0x0000000000000000;
2241
  uint64_t tmodtime = 0x0000000000000000;
2242
  uint32_t tattributes = 0x0000000000000000;
2243
  uint32_t treserved = 0x0000000000000000;
2244
  uint32_t tinputbufferlength = 0;
2245
  uint32_t toutputbufferlength = 0;
2246
  uint32_t tcmd = 0;
2247
  uint32_t calc_crc32 = 0x00000000;
2248
  uint32_t crc32 = 0x00000000;
2249
  uint32_t magic = 0x00000000;
2250
  uint32_t device_id = 0x00000000;
2251
  BYTE * tbuffer = (BYTE *)NULL;
2252
  BYTE * toutbuffer = (BYTE *)NULL;
2253
  void * pdu = (void *)NULL;
2254
  BYTE * buf = (BYTE *)NULL;
2255
  char * cbuf = (char *)NULL;
2256
  char * tpos = NULL;
2257
  char * qpos = NULL;
2258
  char tchar = 0;
2259
2260
  MDBGLOG("redir","port_data_in(): called");
2261
2262
  if (trans == 0) {
2263
    return 0;
2264
  }
2265
2266
  g_memset((char *)tdata,0,sizeof(char)*MAX_STREAM);
2267
  g_memset(&ts,0,sizeof(struct stream));
2268
  ts.data = (char *)tdata;
2269
  ts.p = ts.data;
2270
  ts.end = ts.data;
2271
  ts.size = MAX_STREAM;
2272
  r = &ts;
2273
  g_memset((char *)qdata,0,sizeof(char)*MAX_STREAM);
2274
  g_memset(&qs,0,sizeof(struct stream));
2275
  qs.data = (char *)qdata;
2276
  qs.p = qs.data;
2277
  qs.end = qs.data;
2278
  qs.size = MAX_STREAM;
2279
  q = &qs;
2280
  g_memset((char *)odata,0,sizeof(char)*MAX_STREAM);
2281
  g_memset(&os,0,sizeof(struct stream));
2282
  os.data = (char *)odata;
2283
  os.p = os.data;
2284
  os.end = os.data;
2285
  os.size = MAX_STREAM;
2286
  l = &os;
2287
2288
  s = (struct stream *)trans_get_in_s(trans);
2289
  g_memcpy(l->data,s->data,s->size);
2290
  l->size = s->size;
2291
  if ((s->p - s->data) > 0) {
2292
    l->p += (s->p - s->data);
2293
  }
2294
  if ((s->end - s->data) > 0) {
2295
    l->end = l->data + (s->end - s->data);
2296
  }
2297
  g_memcpy(q->data,s->data,s->size);
2298
  q->size = s->size;
2299
  if ((s->p - s->data) > 0) {
2300
    q->p += (s->p - s->data);
2301
  }
2302
  if ((s->end - s->data) > 0) {
2303
    q->end = q->data + (s->end - s->data);
2304
  }
2305
  // g_hexdump_file("/tmp/taskq_parent_pronto.hexdump",q->data,q->size);
2306
  in_uint32_le(q, magic);
2307
  in_uint32_le(q, rdpport_opcode);
2308
  in_uint32_le(q, size);
2309
  in_uint32_le(q, device_id);
2310
  in_uint32_le(q, fhandle);
2311
  in_uint32_le(q, uniqid);
2312
  in_uint32_le(q, crc32);
2313
2314
  if (size > 0) {
2315
    int tlen = size;
2316
    trans_force_read(trans, tlen);
2317
    s->p += 28;
2318
    calc_crc32 = Crc32_ComputeBuf(0, s->p, tlen);
2319
    MDBGLOG("redir", "INFO\t[%s()]: crc32 = 0x%8.8x, calc_crc32 = 0x%8.8x", __func__, crc32, calc_crc32);
2320
    if ((rdpport_opcode & RDPPORT_READ) == rdpport_opcode) {
2321
      in_uint32_le(s, tsize);
2322
      in_uint64_le(s, toffset);
2323
      tlen -= 12;
2324
    }
2325
    else if ((rdpport_opcode & RDPPORT_WRITE) == rdpport_opcode) {
2326
      in_uint32_le(s, tsize);
2327
      in_uint64_le(s, toffset);
2328
      in_uint8(s, tchar);
2329
      tlen -= (12 + tsize);
2330
//      tlen -= 12;
2331
    }
2332
    else if ((rdpport_opcode & RDPPORT_IOCTL) == rdpport_opcode && rdpport_opcode != 0x00000000) {
2333
      in_uint32_le(s, tcmd);
2334
      in_uint32_le(s, tinputbufferlength);
2335
      in_uint32_le(s, toutputbufferlength);
2336
      if (tinputbufferlength > 0) {
2337
	tbuffer = (BYTE *)g_malloc(sizeof(BYTE) * tinputbufferlength, 1);
2338
	in_uint8a(s, tbuffer, tinputbufferlength);
2339
      }
2340
      tlen -= (12 + tinputbufferlength);
2341
    }
2342
    else if ((rdpport_opcode & RDPPORT_OPEN) == rdpport_opcode) {
2343
      in_uint32_le(s, tflags);
2344
      in_uint32_le(s, tshare);
2345
      in_uint32_le(s, toptions);
2346
      in_uint32_le(s, tattributes);
2347
      tlen -= (16 + tsize);
2348
    }
2349
    if (tlen > 0) {
2350
      cbuf = (char *)g_malloc(sizeof(char) * tlen, 1);
2351
      buf = (BYTE *)g_malloc(sizeof(BYTE) * tlen, 1);
2352
      in_uint8a(s, (char *)cbuf, tlen);
2353
      g_memcpy((char *)buf,cbuf,tlen);
2354
    }
2355
  }
2356
  
2357
  MDBGLOG("redir","\n\n    ** port_data_in(): rdpport_opcode = %8.8x; size = %d; uniqid = %d; fhandle = %d; buf = \"%s\"; tflags = 0x%8.8x; tsize = %d; toffset = %lu\n",rdpport_opcode,size,uniqid,fhandle,(char *)buf,tflags,tsize,toffset);
2358
2359
  if (error == 0) {
2360
    int found = 0;
2361
    TC_MUTEX_LOCK(mutex_cb);
2362
    for (opid = 4; opid < MAX_PENDING; opid++) {
2363
      if (g_callbacks[opid].opid < 1) {
2364
        found = 1;
2365
        break;
2366
      }
2367
    }
2368
    if (found > 0) {
2369
      g_memset((callback *)(&(g_callbacks[opid])), 0, sizeof(callback));
2370
      g_callbacks[opid].opid = opid;
2371
      g_callbacks[opid].type = 1;
2372
      g_callbacks[opid].port = g_port_arr[0];
2373
      g_callbacks[opid].fd = g_port_arr[0]->parent_sck;
2374
      g_callbacks[opid].opcode = rdpport_opcode;
2375
      g_callbacks[opid].CompletionId = opid;
2376
      g_callbacks[opid].trans = g_port_arr[0]->ccon;
2377
      g_callbacks[opid].uniqid = uniqid;
2378
      g_callbacks[opid].FileId = fhandle;
2379
      g_callbacks[opid].setData = &cb_set_data;
2380
      g_callbacks[opid].call = &cb_call;
2381
      g_callbacks[opid].callData = &cb_call_data;
2382
      if (size > 0 && buf != NULL && g_strlen(buf) > 0) {
2383
        g_memcpy(g_callbacks[opid].fname,buf,(size > 511)?511:size);
2384
      }
2385
      cb = &(g_callbacks[opid]);
2386
    }
2387
    if (found < 1) {
2388
      MDBGLOG("redir","ERROR [port_data_in()]: unable to allocate callback slot (opcode = %8.8x; opid = %d)",rdpport_opcode,opid);
2389
      error = -1;
2390
    }
2391
    else if (cb == NULL) {
2392
      MDBGLOG("redir","ERROR [port_data_in()]: failed to assign callback to operation (opcode = %8.8x; opid = %d)",rdpport_opcode,opid);
2393
      error = -1;
2394
    }
2395
    else {
2396
      switch(rdpport_opcode) {
2397
	case RDPPORT_OPEN:
2398
	  MDBGLOG("redir","INFO [port_data_in()]: opcode = RDPPORT_OPEN");
2399
	  {
2400
	    DR_CREATE_REQ ioreq;
2401
	    char fpath[512];
2402
	    BYTE wpath[1024];
2403
	    int cnt = 0;
2404
	    char * iptr = NULL;
2405
	    char * optr = NULL;
2406
	    int inum = 0;
2407
	    int onum = 0;
2408
	    g_memset(&ioreq,0,sizeof(DR_CREATE_REQ));
2409
	    g_memset((char *)fpath,0,sizeof(char)*512);
2410
	    g_memset((BYTE *)wpath,0,sizeof(BYTE)*1024);
2411
	    fpath_length = g_strlen(buf) + 1;
2412
2413
	    iptr = buf;
2414
	    optr = wpath;
2415
	    inum = fpath_length;
2416
	    onum = 1024;
2417
	    g_outstr(&optr,&onum,&iptr,&inum);
2418
	    cnt = fpath_length * 2;
2419
2420
	    pdu = (void *)(&ioreq);
2421
	    construct_DR_CREATE_REQ(&ioreq);
2422
	    if (trans->callback_data != NULL) {
2423
	      ioreq.DeviceIoRequest.DeviceId = ((rdpport_t *)trans->callback_data)->device_id;
2424
	    }
2425
	    else if (g_port_arr != NULL && g_port_arr[0] != NULL) {
2426
	      ioreq.DeviceIoRequest.DeviceId = g_port_arr[0]->device_id;
2427
	    }
2428
	    ioreq.DeviceIoRequest.CompletionId = opid;
2429
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
2430
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
2431
	    ioreq.CreateDisposition = FILE_OPEN;
2432
	    ioreq.CreateOptions = toptions;
2433
	    ioreq.DesiredAccess = tflags;
2434
	    ioreq.SharedAccess = tshare;
2435
	    ioreq.FileAttributes = tattributes;
2436
	    ioreq.PathLength = 0;
2437
	    send_DR_CREATE_REQ(&ioreq, r);
2438
	    MDBGLOG("redir"," ^^ (RDPPORT_OPEN) FileId = %d",ioreq.DeviceIoRequest.FileId);
2439
	  }
2440
	  break;
2441
	case RDPPORT_CLOSE:
2442
	  MDBGLOG("redir","INFO [port_data_in()]: opcode = RDPPORT_CLOSE");
2443
	  {
2444
	    DR_CLOSE_REQ ioreq;
2445
	    g_memset(&ioreq,0,sizeof(DR_CLOSE_REQ));
2446
	    construct_DR_CLOSE_REQ(&ioreq);
2447
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CLOSE;
2448
	    TC_MUTEX_LOCK(mutex_client_devicelist);
2449
	    TC_MUTEX_LOCK(mutex_port_arr);
2450
	    if (g_client_devicelist != NULL && g_client_devicelist->DeviceList != NULL && g_client_devicelist->DeviceList[0] != NULL) {
2451
	      ioreq.DeviceIoRequest.DeviceId = g_client_devicelist->DeviceList[0]->DeviceId;
2452
	    }
2453
	    else if (g_port_arr != NULL && g_port_arr[0] != NULL) {
2454
	      ioreq.DeviceIoRequest.DeviceId = g_port_arr[0]->device_id;
2455
	    }
2456
	    TC_MUTEX_UNLOCK(mutex_port_arr);
2457
	    TC_MUTEX_UNLOCK(mutex_client_devicelist);
2458
	    ioreq.DeviceIoRequest.FileId = fhandle;
2459
	    ioreq.DeviceIoRequest.CompletionId = opid;
2460
	    cb->FileId = fhandle;
2461
	    send_DR_CLOSE_REQ(&ioreq, r);
2462
	    MDBGLOG("redir","port_data_in(): [RDPPORT_CLOSE] request sent (FileId = %d)",ioreq.DeviceIoRequest.FileId);
2463
	  }
2464
	  break;
2465
	case RDPPORT_READ:
2466
	  MDBGLOG("redir","INFO [port_data_in()]: opcode = RDPPORT_READ");
2467
	  {
2468
	    DR_READ_REQ ioreq;
2469
	    construct_DR_READ_REQ(&ioreq);
2470
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_READ;
2471
	    if (trans->callback_data != NULL) {
2472
	      ioreq.DeviceIoRequest.DeviceId = ((rdpport_t *)trans->callback_data)->device_id;
2473
	    }
2474
	    else if (g_port_arr != NULL && g_port_arr[0] != NULL) {
2475
	      ioreq.DeviceIoRequest.DeviceId = g_port_arr[0]->device_id;
2476
	    }
2477
	    ioreq.DeviceIoRequest.CompletionId = opid;
2478
	    ioreq.DeviceIoRequest.FileId = fhandle;
2479
	    cb->opid = opid;
2480
	    cb->FileId = fhandle;
2481
	    ioreq.Length = tsize;
2482
	    ioreq.Offset = toffset;
2483
	    send_DR_READ_REQ(&ioreq, r);
2484
	    MDBGLOG("redir"," ^^ (RDPFS_READ): ioreq.Length = %d; ioreq.Offset = %llu; tsize = %d; toffset = %llu; buf = \"%s\"; ioreq.DeviceIoRequest.DeviceId = %d; ioreq.DeviceIoRequest.FileId = %d; ioreq.DeviceIoRequest.MajorFunction = 0x%8.8x",ioreq.Length,ioreq.Offset,tsize,toffset,buf,ioreq.DeviceIoRequest.DeviceId,ioreq.DeviceIoRequest.FileId,ioreq.DeviceIoRequest.MajorFunction);
2485
	  }
2486
	  break;
2487
	case RDPPORT_WRITE:
2488
	  //MDBGLOG("redir","INFO [port_data_in()]: opcode = RDPPORT_WRITE");
2489
	  {
2490
	    DR_WRITE_REQ ioreq;
2491
	    construct_DR_WRITE_REQ(&ioreq);
2492
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_WRITE;
2493
	    if (trans->callback_data != NULL) {
2494
	      ioreq.DeviceIoRequest.DeviceId = ((rdpport_t *)trans->callback_data)->device_id;
2495
	    }
2496
	    else if (g_port_arr != NULL && g_port_arr[0] != NULL) {
2497
	      ioreq.DeviceIoRequest.DeviceId = g_port_arr[0]->device_id;
2498
	    }
2499
	    ioreq.DeviceIoRequest.CompletionId = opid;
2500
	    ioreq.DeviceIoRequest.FileId = fhandle;
2501
	    ioreq.Length = tsize;
2502
	    toffset = 0;
2503
	    ioreq.Offset = toffset;
2504
	    ioreq.WriteData = (BYTE *)g_malloc(sizeof(BYTE) * ioreq.Length, 1);
2505
	    g_memcpy(ioreq.WriteData, &tchar, sizeof(char));
2506
2507
	    //MDBGLOG("redir"," ^^ (RDPPORT_WRITE): ioreq.WriteData = \"%s\"; ioreq.Length = %d; ioreq.Offset = %d",(unsigned char *)(&(ioreq.WriteData[0])),ioreq.Length,ioreq.Offset);
2508
	    send_DR_WRITE_REQ(&ioreq, r);
2509
	  }
2510
	  break;
2511
	case RDPPORT_IOCTL:
2512
	  MDBGLOG("redir","INFO [port_data_in()]: opcode = RDPPORT_IOCTL (fhandle = %d, tinputbufferlength = %d, toutputbufferlength = %d, tcmd = 0x%8.8x)", fhandle, tinputbufferlength, toutputbufferlength, tcmd);
2513
	  {
2514
	    DR_CONTROL_REQ ioctlreq;
2515
	    construct_DR_CONTROL_REQ(&ioctlreq);
2516
	    if (trans->callback_data != NULL) {
2517
	      ioctlreq.DeviceIoRequest.DeviceId = ((rdpport_t *)trans->callback_data)->device_id;
2518
	    }
2519
	    else if (g_port_arr != NULL && g_port_arr[0] != NULL) {
2520
	      ioctlreq.DeviceIoRequest.DeviceId = g_port_arr[0]->device_id;
2521
	    }
2522
	    ioctlreq.DeviceIoRequest.CompletionId = opid;
2523
	    ioctlreq.DeviceIoRequest.FileId = fhandle;
2524
	    ioctlreq.DeviceIoRequest.MajorFunction = IRP_MJ_DEVICE_CONTROL;
2525
	    ioctlreq.DeviceIoRequest.MinorFunction = 0x00000000;
2526
	    ioctlreq.InputBufferLength = tinputbufferlength;
2527
	    ioctlreq.OutputBufferLength = toutputbufferlength;
2528
	    ioctlreq.IoControlCode = tcmd;
2529
	    if (tbuffer != NULL) {
2530
	      ioctlreq.InputBuffer = tbuffer;
2531
	    }
2532
	    send_DR_CONTROL_REQ(&ioctlreq, r);
2533
	  }
2534
	  break;
2535
	case RDPPORT_INIT:
2536
	  MDBGLOG("redir","INFO [port_data_in()]: opcode = RDPPORT_INIT");
2537
	  {
2538
	  }
2539
	  break;
2540
	case RDPPORT_DESTROY:
2541
	  MDBGLOG("redir","INFO [port_data_in()]: opcode = RDPPORT_DESTROY");
2542
	  {
2543
	  }
2544
	  break;
2545
        default:
2546
  	  MDBGLOG("redir","ERROR [port_data_in()]: unrecognized opcode (0x%8.8x)",rdpport_opcode);
2547
	  r = trans_get_out_s(trans, MAX_STREAM);
2548
	  magic = RDP_PACKET_MAGIC;
2549
	  crc32 = 0x00000000;
2550
	  size = 0x00000000;
2551
	  out_uint32_le(r, magic);
2552
	  out_uint32_le(r, RDPPORT_ERROR);
2553
	  out_uint32_le(r, size);
2554
	  out_uint32_le(r, device_id);
2555
	  out_uint32_le(r, fhandle);
2556
	  out_uint32_le(r, uniqid);
2557
	  out_uint32_le(r, crc32);
2558
	  s_mark_end(r);
2559
	  trans_force_write(trans);
2560
	  r->end = r->data;
2561
  	  break;
2562
      }
2563
      /* send the assembled PDU to the RDP client: */
2564
      //MDBGLOG("redir","[port_data_in()]: sending PDU to RDP channel...");
2565
      s_mark_end(r);
2566
      size = r->end - r->data;
2567
      if (size > 0) {
2568
	TC_MUTEX_LOCK(mutex_out);
2569
	error = send_channel_data(g_rdpdr_chan_id, r->data, size);
2570
	TC_MUTEX_UNLOCK(mutex_out);
2571
	//MDBGLOG("redir","[port_data_in()]: sent. (error = %d; g_rdpdr_chan_id = %d)",error,g_rdpdr_chan_id);
2572
	//// g_hexdump_file("/tmp/taskq_port_pdu.hexdump", r->data, size);
2573
	if (rdpport_opcode == RDPPORT_READ) {
2574
	  //// g_hexdump_file("/tmp/taskq_port_pdu_read.hexdump", r->data, size);
2575
	}
2576
	else if (rdpport_opcode == RDPPORT_WRITE) {
2577
	  //// g_hexdump_file("/tmp/taskq_port_pdu_write.hexdump", r->data, size);
2578
	}
2579
      }
2580
      else {
2581
	MDBGLOG("redir","ERROR [port_data_in()]: output PDU is empty (size == 0)");
2582
      }
2583
    }
2584
    TC_MUTEX_UNLOCK(mutex_cb);
2585
  }
2586
  return error;
2587
}
2588
2589
/*****************************************************************************/
2590
static int APP_CC
2591
printer_data_in(struct trans * trans) {
2592
  int rv = 0;
2593
  struct stream * s = (struct stream *)NULL;
2594
  char odata[MAX_STREAM];
2595
  struct stream os;
2596
  char qdata[MAX_STREAM];
2597
  struct stream qs;
2598
  char tdata[MAX_STREAM];
2599
  struct stream ts;
2600
  struct stream * r = (struct stream *)NULL;
2601
  struct stream * q = (struct stream *)NULL;
2602
  struct stream * l = (struct stream *)NULL;
2603
  callback * cb = (callback *)NULL;
2604
  int fpath_length = 0;
2605
  int rdpprint_opcode = 0;
2606
  int size = 0;
2607
  int error = 0;
2608
  int idx = 0;
2609
  int opid = 0;
2610
  int fhandle = 0;
2611
  int uniqid = 0;
2612
  uint32_t tflags = 0x00000000;
2613
  uint32_t toptions = 0x00000000;
2614
  uint32_t tshare = 0x00000000;
2615
  uint32_t tsize = 0x00000000;
2616
  uint64_t toffset = 0x0000000000000000;
2617
  uint64_t tchangetime = 0x0000000000000000;
2618
  uint64_t tactime = 0x0000000000000000;
2619
  uint64_t tmodtime = 0x0000000000000000;
2620
  uint32_t tattributes = 0x0000000000000000;
2621
  uint32_t treserved = 0x0000000000000000;
2622
  uint32_t tinputbufferlength = 0;
2623
  uint32_t toutputbufferlength = 0;
2624
  uint32_t tcmd = 0;
2625
  BYTE * tbuffer = (BYTE *)NULL;
2626
  void * pdu = (void *)NULL;
2627
  BYTE * buf = (BYTE *)NULL;
2628
  char * cbuf = (char *)NULL;
2629
  char * tpos = NULL;
2630
  char * qpos = NULL;
2631
  uint32_t crc32 = 0x00000000;
2632
  uint32_t calc_crc32 = 0x00000000;
2633
  uint32_t magic = 0x00000000;
2634
  uint32_t device_id = 0x00000000;
2635
2636
  MDBGLOG("redir","printer_data_in(): called");
2637
2638
  if (trans == 0) {
2639
    return 0;
2640
  }
2641
2642
  g_memset((char *)tdata,0,sizeof(char)*MAX_STREAM);
2643
  g_memset(&ts,0,sizeof(struct stream));
2644
  ts.data = (char *)tdata;
2645
  ts.p = ts.data;
2646
  ts.end = ts.data;
2647
  ts.size = MAX_STREAM;
2648
  r = &ts;
2649
  g_memset((char *)qdata,0,sizeof(char)*MAX_STREAM);
2650
  g_memset(&qs,0,sizeof(struct stream));
2651
  qs.data = (char *)qdata;
2652
  qs.p = qs.data;
2653
  qs.end = qs.data;
2654
  qs.size = MAX_STREAM;
2655
  q = &qs;
2656
  g_memset((char *)odata,0,sizeof(char)*MAX_STREAM);
2657
  g_memset(&os,0,sizeof(struct stream));
2658
  os.data = (char *)odata;
2659
  os.p = os.data;
2660
  os.end = os.data;
2661
  os.size = MAX_STREAM;
2662
  l = &os;
2663
2664
  s = (struct stream *)trans_get_in_s(trans);
2665
  g_memcpy(l->data,s->data,s->size);
2666
  l->size = s->size;
2667
  if ((s->p - s->data) > 0) {
2668
    l->p += (s->p - s->data);
2669
  }
2670
  if ((s->end - s->data) > 0) {
2671
    l->end = l->data + (s->end - s->data);
2672
  }
2673
  g_memcpy(q->data,s->data,s->size);
2674
  q->size = s->size;
2675
  if ((s->p - s->data) > 0) {
2676
    q->p += (s->p - s->data);
2677
  }
2678
  if ((s->end - s->data) > 0) {
2679
    q->end = q->data + (s->end - s->data);
2680
  }
2681
  // g_hexdump_file("/tmp/taskq_parent_pronto.hexdump",q->data,q->size);
2682
  in_uint32_le(q, magic);
2683
  in_uint32_le(q, rdpprint_opcode);
2684
  in_uint32_le(q, size);
2685
  in_uint32_le(q, device_id);
2686
  in_uint32_le(q, fhandle);
2687
  in_uint32_le(q, uniqid);
2688
  in_uint32_le(q, crc32);
2689
2690
  if (size > 0) {
2691
    int tlen = size;
2692
    trans_force_read(trans, tlen);
2693
    s->p += 28;
2694
    calc_crc32 = Crc32_ComputeBuf(0, s->p, tlen);
2695
    MDBGLOG("redir", "INFO\t[%s()]: crc32 = 0x%8.8x, calc_crc32 = 0x%8.8x", __func__, crc32, calc_crc32);
2696
    if ((rdpprint_opcode & RDPPRINT_READ) == RDPPRINT_READ) {
2697
      in_uint32_le(s, tsize);
2698
      in_uint64_le(s, toffset);
2699
      tlen -= 12;
2700
    }
2701
    else if ((rdpprint_opcode & RDPPRINT_WRITE) == RDPPRINT_WRITE) {
2702
      in_uint32_le(s, tsize);
2703
      in_uint64_le(s, toffset);
2704
      tlen -= (12 + tsize);
2705
    }
2706
    else if ((rdpprint_opcode & RDPPRINT_IOCTL) == RDPPRINT_IOCTL) {
2707
      in_uint32_le(s, tcmd);
2708
      in_uint32_le(s, tinputbufferlength);
2709
      toutputbufferlength = 4096;
2710
      if (tinputbufferlength > 0) {
2711
	tbuffer = (BYTE *)g_malloc(sizeof(BYTE) * tinputbufferlength, 1);
2712
	in_uint8a(s, tbuffer, tinputbufferlength);
2713
      }
2714
      tlen -= (8 + tinputbufferlength + tsize);
2715
    }
2716
    else if ((rdpprint_opcode & RDPPRINT_OPEN) == RDPPRINT_OPEN) {
2717
      in_uint32_le(s, tflags);
2718
      in_uint32_le(s, tshare);
2719
      in_uint32_le(s, toptions);
2720
      in_uint32_le(s, tattributes);
2721
      //tlen -= 8;
2722
      tlen -= (16 + tsize);
2723
    }
2724
    cbuf = (char *)g_malloc(sizeof(char) * tlen, 1);
2725
    buf = (BYTE *)g_malloc(sizeof(BYTE) * tlen, 1);
2726
    in_uint8a(s, (char *)cbuf, tlen);
2727
    g_memcpy((char *)buf,cbuf,tlen);
2728
  }
2729
  
2730
  MDBGLOG("redir","INFO\t[%s()]:    ** printer_data_in(): rdpprint_opcode = %8.8x; size = %d; uniqid = %d; fhandle = %d; buf = \"%s\"; tflags = 0x%8.8x; tsize = %d; toffset = %lu",__func__,rdpprint_opcode,size,uniqid,fhandle,(char *)buf,tflags,tsize,toffset);
2731
2732
  if (error == 0) {
2733
    TC_MUTEX_LOCK(mutex_cb);
2734
    int found = 0;
2735
    for (opid = 4; opid < MAX_PENDING; opid++) {
2736
      if (g_callbacks[opid].opid < 1) {
2737
        found = 1;
2738
        break;
2739
      }
2740
    }
2741
    if (found > 0) {
2742
      g_memset((callback *)(&(g_callbacks[opid])), 0, sizeof(callback));
2743
      g_callbacks[opid].opid = opid;
2744
      g_callbacks[opid].type = 1;
2745
      g_callbacks[opid].printer = g_printer_arr[0];
2746
      g_callbacks[opid].fd = g_printer_arr[0]->parent_sck;
2747
      g_callbacks[opid].opcode = rdpprint_opcode;
2748
      g_callbacks[opid].CompletionId = opid;
2749
      g_callbacks[opid].trans = g_printer_arr[0]->ccon;
2750
      g_callbacks[opid].uniqid = uniqid;
2751
      g_callbacks[opid].FileId = fhandle;
2752
      g_callbacks[opid].setData = &cb_set_data;
2753
      g_callbacks[opid].call = &cb_call;
2754
      g_callbacks[opid].callData = &cb_call_data;
2755
      g_memcpy(g_callbacks[opid].fname,buf,(size > 511)?511:size);
2756
      cb = &(g_callbacks[opid]);
2757
    }
2758
    if (found < 1) {
2759
      MDBGLOG("redir","ERROR [printer_data_in()]: unable to allocate callback slot (opcode = %8.8x; opid = %d)",rdpprint_opcode,opid);
2760
      error = -1;
2761
    }
2762
    else if (cb == NULL) {
2763
      MDBGLOG("redir","ERROR [printer_data_in()]: failed to assign callback to operation (opcode = %8.8x; opid = %d)",rdpprint_opcode,opid);
2764
      error = -1;
2765
    }
2766
    else {
2767
      switch(rdpprint_opcode) {
2768
        default:
2769
  	  MDBGLOG("redir","ERROR [printer_data_in()]: unrecognized opcode (0x%8.8x)",rdpprint_opcode);
2770
	  r = trans_get_out_s(trans, MAX_STREAM);
2771
	  magic = RDP_PACKET_MAGIC;
2772
	  crc32 = 0x00000000;
2773
	  size = 0x00000000;
2774
	  out_uint32_le(r, magic);
2775
	  out_uint32_le(r, RDPPRINT_ERROR);
2776
	  out_uint32_le(r, size);
2777
	  out_uint32_le(r, device_id);
2778
	  out_uint32_le(r, fhandle);
2779
	  out_uint32_le(r, uniqid);
2780
	  out_uint32_le(r, crc32);
2781
	  s_mark_end(r);
2782
	  trans_force_write(trans);
2783
	  r->end = r->data;
2784
  	  break;
2785
      }
2786
      /* send the assembled PDU to the RDP client: */
2787
      MDBGLOG("redir","[printer_data_in()]: sending PDU to RDP channel...");
2788
      s_mark_end(r);
2789
      size = r->end - r->data;
2790
      if (size > 0) {
2791
	TC_MUTEX_LOCK(mutex_out);
2792
	error = send_channel_data(g_rdpdr_chan_id, r->data, size);
2793
	TC_MUTEX_UNLOCK(mutex_out);
2794
	MDBGLOG("redir","[printer_data_in()]: sent. (error = %d; g_rdpdr_chan_id = %d)",error,g_rdpdr_chan_id);
2795
	// g_hexdump_file("/tmp/taskq_printer_pdu.hexdump", r->data, size);
2796
	if (rdpprint_opcode == RDPPRINT_READ) {
2797
	  // g_hexdump_file("/tmp/taskq_printer_pdu_read.hexdump", r->data, size);
2798
	}
2799
      }
2800
      else {
2801
	MDBGLOG("redir","ERROR [printer_data_in()]: output PDU is empty (size == 0)");
2802
      }
2803
    }
2804
    TC_MUTEX_UNLOCK(mutex_cb);
2805
  }
2806
  return error;
2807
}
2808
2809
/*****************************************************************************/
2810
static int APP_CC
2811
smartcard_data_in(struct trans * trans) {
2812
  int rv = 0;
2813
  struct stream * s = (struct stream *)NULL;
2814
  char odata[MAX_STREAM];
2815
  struct stream os;
2816
  char qdata[MAX_STREAM];
2817
  struct stream qs;
2818
  char tdata[MAX_STREAM];
2819
  struct stream ts;
2820
  struct stream * r = (struct stream *)NULL;
2821
  struct stream * q = (struct stream *)NULL;
2822
  struct stream * l = (struct stream *)NULL;
2823
  callback * cb = (callback *)NULL;
2824
  int fpath_length = 0;
2825
  int rdpsc_opcode = 0;
2826
  int size = 0;
2827
  int error = 0;
2828
  int idx = 0;
2829
  int opid = 0;
2830
  int fhandle = 0;
2831
  int uniqid = 0;
2832
  uint32_t tflags = 0x00000000;
2833
  uint32_t toptions = 0x00000000;
2834
  uint32_t tshare = 0x00000000;
2835
  uint32_t tsize = 0x00000000;
2836
  uint64_t toffset = 0x0000000000000000;
2837
  uint64_t tchangetime = 0x0000000000000000;
2838
  uint64_t tactime = 0x0000000000000000;
2839
  uint64_t tmodtime = 0x0000000000000000;
2840
  uint32_t tattributes = 0x0000000000000000;
2841
  uint32_t treserved = 0x0000000000000000;
2842
  uint32_t tinputbufferlength = 0;
2843
  uint32_t toutputbufferlength = 0;
2844
  uint32_t tcmd = 0;
2845
  BYTE * tbuffer = (BYTE *)NULL;
2846
  void * pdu = (void *)NULL;
2847
  BYTE * buf = (BYTE *)NULL;
2848
  char * cbuf = (char *)NULL;
2849
  char * tpos = NULL;
2850
  char * qpos = NULL;
2851
  uint32_t crc32 = 0x00000000;
2852
  uint32_t magic = 0x00000000;
2853
  uint32_t device_id = 0x00000000;
2854
  uint32_t calc_crc32 = 0x00000000;
2855
2856
  MDBGLOG("redir","smartcard_data_in(): called");
2857
2858
  if (trans == 0) {
2859
    return 0;
2860
  }
2861
2862
  g_memset((char *)tdata,0,sizeof(char)*MAX_STREAM);
2863
  g_memset(&ts,0,sizeof(struct stream));
2864
  ts.data = (char *)tdata;
2865
  ts.p = ts.data;
2866
  ts.end = ts.data;
2867
  ts.size = MAX_STREAM;
2868
  r = &ts;
2869
  g_memset((char *)qdata,0,sizeof(char)*MAX_STREAM);
2870
  g_memset(&qs,0,sizeof(struct stream));
2871
  qs.data = (char *)qdata;
2872
  qs.p = qs.data;
2873
  qs.end = qs.data;
2874
  qs.size = MAX_STREAM;
2875
  q = &qs;
2876
  g_memset((char *)odata,0,sizeof(char)*MAX_STREAM);
2877
  g_memset(&os,0,sizeof(struct stream));
2878
  os.data = (char *)odata;
2879
  os.p = os.data;
2880
  os.end = os.data;
2881
  os.size = MAX_STREAM;
2882
  l = &os;
2883
2884
  s = (struct stream *)trans_get_in_s(trans);
2885
  g_memcpy(l->data,s->data,s->size);
2886
  l->size = s->size;
2887
  if ((s->p - s->data) > 0) {
2888
    l->p += (s->p - s->data);
2889
  }
2890
  if ((s->end - s->data) > 0) {
2891
    l->end = l->data + (s->end - s->data);
2892
  }
2893
  g_memcpy(q->data,s->data,s->size);
2894
  q->size = s->size;
2895
  if ((s->p - s->data) > 0) {
2896
    q->p += (s->p - s->data);
2897
  }
2898
  if ((s->end - s->data) > 0) {
2899
    q->end = q->data + (s->end - s->data);
2900
  }
2901
  // g_hexdump_file("/tmp/taskq_parent_pronto.hexdump",q->data,q->size);
2902
  in_uint32_le(q, magic);
2903
  in_uint32_le(q, rdpsc_opcode);
2904
  in_uint32_le(q, size);
2905
  in_uint32_le(q, device_id);
2906
  in_uint32_le(q, fhandle);
2907
  in_uint32_le(q, uniqid);
2908
  in_uint32_le(q, crc32);
2909
2910
  if (size > 0) {
2911
    int tlen = size;
2912
    trans_force_read(trans, tlen);
2913
    s->p += 28;
2914
    calc_crc32 = Crc32_ComputeBuf(0, s->p, tlen);
2915
    MDBGLOG("redir", "INFO\t[%s()]: crc32 = 0x%8.8x, calc_crc32 = 0x%8.8x", __func__, crc32, calc_crc32);
2916
    if ((rdpsc_opcode & RDPSC_READ) == RDPSC_READ) {
2917
      in_uint32_le(s, tsize);
2918
      in_uint64_le(s, toffset);
2919
      tlen -= 12;
2920
    }
2921
    else if ((rdpsc_opcode & RDPSC_WRITE) == RDPSC_WRITE) {
2922
      in_uint32_le(s, tsize);
2923
      in_uint64_le(s, toffset);
2924
      tlen -= (12 + tsize);
2925
    }
2926
    else if ((rdpsc_opcode & RDPSC_IOCTL) == RDPSC_IOCTL) {
2927
      in_uint32_le(s, tcmd);
2928
      in_uint32_le(s, tinputbufferlength);
2929
      toutputbufferlength = 4096;
2930
      if (tinputbufferlength > 0) {
2931
	tbuffer = (BYTE *)g_malloc(sizeof(BYTE) * tinputbufferlength, 1);
2932
	in_uint8a(s, tbuffer, tinputbufferlength);
2933
      }
2934
      tlen -= (8 + tinputbufferlength + tsize);
2935
    }
2936
    else if ((rdpsc_opcode & RDPSC_OPEN) == RDPSC_OPEN) {
2937
      in_uint32_le(s, tflags);
2938
      in_uint32_le(s, tshare);
2939
      in_uint32_le(s, toptions);
2940
      in_uint32_le(s, tattributes);
2941
      //tlen -= 8;
2942
      tlen -= (16 + tsize);
2943
    }
2944
    cbuf = (char *)g_malloc(sizeof(char) * tlen, 1);
2945
    buf = (BYTE *)g_malloc(sizeof(BYTE) * tlen, 1);
2946
    in_uint8a(s, (char *)cbuf, tlen);
2947
    g_memcpy((char *)buf,cbuf,tlen);
2948
  }
2949
  
2950
  MDBGLOG("redir","\n\n    ** smartcard_data_in(): rdpsc_opcode = %8.8x; size = %d; uniqid = %d; fhandle = %d; buf = \"%s\"; tflags = 0x%8.8x; tsize = %d; toffset = %lu\n",rdpsc_opcode,size,uniqid,fhandle,(char *)buf,tflags,tsize,toffset);
2951
2952
  if (error == 0) {
2953
    int found = 0;
2954
    TC_MUTEX_LOCK(mutex_cb);
2955
    for (opid = 4; opid < MAX_PENDING; opid++) {
2956
      if (g_callbacks[opid].opid < 1) {
2957
        found = 1;
2958
        break;
2959
      }
2960
    }
2961
    if (found > 0) {
2962
      g_memset((callback *)(&(g_callbacks[opid])), 0, sizeof(callback));
2963
      g_callbacks[opid].opid = opid;
2964
      g_callbacks[opid].type = 1;
2965
      g_callbacks[opid].smartcard = g_smartcard_arr[0];
2966
      g_callbacks[opid].fd = g_smartcard_arr[0]->parent_sck;
2967
      g_callbacks[opid].opcode = rdpsc_opcode;
2968
      g_callbacks[opid].CompletionId = opid;
2969
      g_callbacks[opid].trans = g_smartcard_arr[0]->ccon;
2970
      g_callbacks[opid].uniqid = uniqid;
2971
      g_callbacks[opid].FileId = fhandle;
2972
      g_callbacks[opid].setData = &cb_set_data;
2973
      g_callbacks[opid].call = &cb_call;
2974
      g_callbacks[opid].callData = &cb_call_data;
2975
      g_memcpy(g_callbacks[opid].fname,buf,(size > 511)?511:size);
2976
      cb = &(g_callbacks[opid]);
2977
    }
2978
    if (found < 1) {
2979
      MDBGLOG("redir","ERROR [smartcard_data_in()]: unable to allocate callback slot (opcode = %8.8x; opid = %d)",rdpsc_opcode,opid);
2980
      error = -1;
2981
    }
2982
    else if (cb == NULL) {
2983
      MDBGLOG("redir","ERROR [smartcard_data_in()]: failed to assign callback to operation (opcode = %8.8x; opid = %d)",rdpsc_opcode,opid);
2984
      error = -1;
2985
    }
2986
    else {
2987
      switch(rdpsc_opcode) {
2988
        default:
2989
  	  MDBGLOG("redir","ERROR [smartcard_data_in()]: unrecognized opcode (0x%8.8x)",rdpsc_opcode);
2990
	  r = trans_get_out_s(trans, MAX_STREAM);
2991
	  size = 0x00000000;
2992
	  crc32 = 0x00000000;
2993
	  magic = RDP_PACKET_MAGIC;
2994
	  out_uint32_le(r, magic);
2995
	  out_uint32_le(r, RDPSC_ERROR);
2996
	  out_uint32_le(r, size);
2997
	  out_uint32_le(r, device_id);
2998
	  out_uint32_le(r, fhandle);
2999
	  out_uint32_le(r, uniqid);
3000
	  out_uint32_le(r, crc32);
3001
	  s_mark_end(r);
3002
	  trans_force_write(trans);
3003
	  r->end = r->data;
3004
  	  break;
3005
      }
3006
      /* send the assembled PDU to the RDP client: */
3007
      MDBGLOG("redir","[smartcard_data_in()]: sending PDU to RDP channel...");
3008
      s_mark_end(r);
3009
      size = r->end - r->data;
3010
      if (size > 0) {
3011
	TC_MUTEX_LOCK(mutex_out);
3012
	error = send_channel_data(g_rdpdr_chan_id, r->data, size);
3013
	TC_MUTEX_UNLOCK(mutex_out);
3014
	MDBGLOG("redir","[smartcard_data_in()]: sent. (error = %d; g_rdpdr_chan_id = %d)",error,g_rdpdr_chan_id);
3015
	// g_hexdump_file("/tmp/taskq_smartcard_pdu.hexdump", r->data, size);
3016
	if (rdpsc_opcode == RDPSC_READ) {
3017
	  // g_hexdump_file("/tmp/taskq_smartcard_pdu_read.hexdump", r->data, size);
3018
	}
3019
      }
3020
      else {
3021
	MDBGLOG("redir","ERROR [smartcard_data_in()]: output PDU is empty (size == 0)");
3022
      }
3023
    }
3024
    TC_MUTEX_UNLOCK(mutex_cb);
3025
  }
3026
  return error;
3027
}
3028
3029
/*****************************************************************************/
3030
static int APP_CC
3031
filesystem_data_in(struct trans * trans) {
3032
  struct stream * s = (struct stream *)NULL;
3033
  char odata[MAX_STREAM];
3034
  struct stream os;
3035
  char qdata[MAX_STREAM];
3036
  struct stream qs;
3037
  char tdata[MAX_STREAM];
3038
  struct stream ts;
3039
  struct stream * r = (struct stream *)NULL;
3040
  struct stream * q = (struct stream *)NULL;
3041
  struct stream * l = (struct stream *)NULL;
3042
  callback * cb = (callback *)NULL;
3043
  int fpath_length = 0;
3044
  int rdpfs_opcode = 0;
3045
  int size = 0;
3046
  int error = 0;
3047
  int idx = 0;
3048
  int opid = 0;
3049
  int fhandle = 0;
3050
  int uniqid = 0;
3051
  uint32_t tflags = 0x00000000;
3052
  uint32_t toptions = 0x00000000;
3053
  uint32_t tshare = 0x00000000;
3054
  uint32_t tsize = 0x00000000;
3055
  uint64_t toffset = 0x0000000000000000;
3056
  uint64_t tchangetime = 0x0000000000000000;
3057
  uint64_t tactime = 0x0000000000000000;
3058
  uint64_t tmodtime = 0x0000000000000000;
3059
  uint32_t tattributes = 0x0000000000000000;
3060
  uint32_t treserved = 0x0000000000000000;
3061
  uint32_t tinputbufferlength = 0;
3062
  uint32_t toutputbufferlength = 0;
3063
  uint32_t tcmd = 0;
3064
  BYTE * tbuffer = (BYTE *)NULL;
3065
  void * pdu = (void *)NULL;
3066
  BYTE * buf = (BYTE *)NULL;
3067
  char * cbuf = (char *)NULL;
3068
  char * tpos = NULL;
3069
  char * qpos = NULL;
3070
  uint32_t crc32 = 0x00000000;
3071
  uint32_t calc_crc32 = 0x00000000;
3072
  uint32_t magic = 0x00000000;
3073
  uint32_t device_id = 0x00000000;
3074
3075
  MDBGLOG("redir","INFO\t[%s()]: called (trans = %p; trans->callback_data = %p; trans->callback_data->device_id = %d) [%d, %d]",__func__,trans,trans->callback_data,((callback *)(trans->callback_data))->device_id,g_getpid(),g_gettid());
3076
3077
  if (trans == 0) {
3078
    return 0;
3079
  }
3080
3081
  g_memset((char *)tdata,0,sizeof(char)*MAX_STREAM);
3082
  g_memset(&ts,0,sizeof(struct stream));
3083
  ts.data = (char *)tdata;
3084
  ts.p = ts.data;
3085
  ts.end = ts.data;
3086
  ts.size = MAX_STREAM;
3087
  r = &ts;
3088
  g_memset((char *)qdata,0,sizeof(char)*MAX_STREAM);
3089
  g_memset(&qs,0,sizeof(struct stream));
3090
  qs.data = (char *)qdata;
3091
  qs.p = qs.data;
3092
  qs.end = qs.data;
3093
  qs.size = MAX_STREAM;
3094
  q = &qs;
3095
  g_memset((char *)odata,0,sizeof(char)*MAX_STREAM);
3096
  g_memset(&os,0,sizeof(struct stream));
3097
  os.data = (char *)odata;
3098
  os.p = os.data;
3099
  os.end = os.data;
3100
  os.size = MAX_STREAM;
3101
  l = &os;
3102
3103
  s = (struct stream *)trans_get_in_s(trans);
3104
  g_memcpy(l->data,s->data,s->size);
3105
  l->size = s->size;
3106
  if ((s->p - s->data) > 0) {
3107
    l->p += (s->p - s->data);
3108
  }
3109
  if ((s->end - s->data) > 0) {
3110
    l->end = l->data + (s->end - s->data);
3111
  }
3112
  g_memcpy(q->data,s->data,s->size);
3113
  q->size = s->size;
3114
  if ((s->p - s->data) > 0) {
3115
    q->p += (s->p - s->data);
3116
  }
3117
  if ((s->end - s->data) > 0) {
3118
    q->end = q->data + (s->end - s->data);
3119
  }
3120
  // g_hexdump_file("/tmp/taskq_parent_pronto.hexdump",q->data,q->size);
3121
  in_uint32_le(q, magic);
3122
  in_uint32_le(q, rdpfs_opcode);
3123
  in_uint32_le(q, size);
3124
  in_uint32_le(q, device_id);
3125
  in_uint32_le(q, fhandle);
3126
  in_uint32_le(q, uniqid);
3127
  in_uint32_le(q, crc32);
3128
3129
  if (size > 0) {
3130
    int tlen = size;
3131
    trans_force_read(trans, tlen);
3132
    s->p += 28;
3133
    calc_crc32 = Crc32_ComputeBuf(0, s->p, tlen);
3134
    if ((rdpfs_opcode & RDPFS_READ) == rdpfs_opcode) {
3135
      in_uint32_le(s, tsize);
3136
      in_uint64_le(s, toffset);
3137
      tlen -= 12;
3138
    }
3139
    else if ((rdpfs_opcode & RDPFS_WRITE) == rdpfs_opcode) {
3140
      in_uint32_le(s, tsize);
3141
      in_uint64_le(s, toffset);
3142
      tlen -= (12 + tsize);
3143
    }
3144
    else if ((rdpfs_opcode & RDPFS_FTRUNCATE) == rdpfs_opcode || (rdpfs_opcode & RDPFS_TRUNCATE) == rdpfs_opcode) {
3145
      in_uint64_le(s, toffset);
3146
      tlen -= 8;
3147
    }
3148
    else if ((rdpfs_opcode & RDPFS_UTIME) == rdpfs_opcode) {
3149
      in_uint64_le(s, tactime);
3150
      in_uint64_le(s, tmodtime);
3151
      tlen -= 16;
3152
    }
3153
    else if ((rdpfs_opcode & RDPFS_FSCTL) == rdpfs_opcode) {
3154
      in_uint32_le(s, tcmd);
3155
      in_uint32_le(s, tinputbufferlength);
3156
      toutputbufferlength = 4096;
3157
      if (tinputbufferlength > 0) {
3158
	tbuffer = (BYTE *)g_malloc(sizeof(BYTE) * tinputbufferlength, 1);
3159
	in_uint8a(s, tbuffer, tinputbufferlength);
3160
      }
3161
      tlen -= (8 + tinputbufferlength + tsize);
3162
    }
3163
    else if ((rdpfs_opcode & RDPFS_OPEN) == rdpfs_opcode || (rdpfs_opcode & RDPFS_CREATE) == rdpfs_opcode) {
3164
      in_uint32_le(s, tflags);
3165
      in_uint32_le(s, tshare);
3166
      in_uint32_le(s, toptions);
3167
      in_uint32_le(s, tattributes);
3168
      //tlen -= 8;
3169
      tlen -= (16 + tsize);
3170
    }
3171
    cbuf = (char *)g_malloc(sizeof(char) * tlen, 1);
3172
    buf = (BYTE *)g_malloc(sizeof(BYTE) * tlen, 1);
3173
    in_uint8a(s, (char *)cbuf, tlen);
3174
    g_memcpy((char *)buf,cbuf,tlen);
3175
  }
3176
  
3177
  MDBGLOG("redir","INFO\t[%s()]: ** rdpfs_opcode = %8.8x; size = %d; uniqid = %d; fhandle = %d; buf = \"%s\"; tflags = 0x%8.8x; tsize = %d; toffset = %lu\n",__func__,rdpfs_opcode,size,uniqid,fhandle,(char *)buf,tflags,tsize,toffset);
3178
  MDBGLOG("redir","INFO\t[%s()]: magic = 0x%8.8x, crc32 = 0x%8.8x, calc_crc32 = 0x%8.8x", __func__, magic, crc32, calc_crc32);
3179
3180
  if (error == 0) {
3181
    int found = 0;
3182
    TC_MUTEX_LOCK(mutex_cb);
3183
    for (opid = 4; opid < MAX_PENDING; opid++) {
3184
      if (g_callbacks[opid].opid < 1) {
3185
	found = 1;
3186
	break;
3187
      }
3188
    }
3189
    if (found > 0) {
3190
      g_memset((callback *)(&(g_callbacks[opid])), 0, sizeof(callback));
3191
      g_callbacks[opid].opid = opid;
3192
      g_callbacks[opid].type = 1;
3193
      TC_MUTEX_LOCK(mutex_fs_arr);
3194
      g_callbacks[opid].fs = g_fs_arr[0];
3195
      g_callbacks[opid].fd = g_fs_arr[0]->parent_sck;
3196
      g_callbacks[opid].opcode = rdpfs_opcode;
3197
      g_callbacks[opid].CompletionId = opid;
3198
      g_callbacks[opid].trans = g_fs_arr[0]->ccon;
3199
      TC_MUTEX_UNLOCK(mutex_fs_arr);
3200
      g_callbacks[opid].uniqid = uniqid;
3201
      g_callbacks[opid].FileId = fhandle;
3202
      g_callbacks[opid].setData = &cb_set_data;
3203
      g_callbacks[opid].call = &cb_call;
3204
      g_callbacks[opid].callData = &cb_call_data;
3205
      g_callbacks[opid].device_id = device_id;
3206
      g_memcpy(g_callbacks[opid].fname,buf,(size > 511)?511:size);
3207
      cb = &(g_callbacks[opid]);
3208
    }
3209
    if (found < 1) {
3210
      MDBGLOG("redir","ERROR\t[%s()]: unable to allocate callback slot (opcode = %8.8x; opid = %d)",__func__,rdpfs_opcode,opid);
3211
      error = -1;
3212
    }
3213
    else if (cb == NULL) {
3214
      MDBGLOG("redir","ERROR\t[%s()]: failed to assign callback to operation (opcode = %8.8x; opid = %d)",__func__,rdpfs_opcode,opid);
3215
      error = -1;
3216
    }
3217
    else {
3218
      if (device_id == 0 && trans->callback_data != NULL) {
3219
	device_id = ((rdpfs *)trans->callback_data)->device_id;
3220
      }
3221
      switch(rdpfs_opcode) {
3222
	case RDPFS_GETATTR:
3223
	case RDPFS_FGETATTR:
3224
	  if (rdpfs_opcode == RDPFS_FGETATTR) {
3225
	    MDBGLOG("redir","INFO\t[%s()]: ^^ (RDPFS_FGETATTR): device_id = %d; fhandle = %d; uniqid = %d",__func__,device_id,fhandle,uniqid);
3226
	  }
3227
	  else {
3228
	    MDBGLOG("redir","INFO\t[%s()]: ^^ (RDPFS_GETATTR): device_id = %d; fhandle = %d; uniqid = %d",__func__,device_id,fhandle,uniqid);
3229
	  }
3230
	  {
3231
	    DR_DRIVE_QUERY_INFORMATION_REQ ioreq;
3232
	    DECLARE_GETATTR(tmp);
3233
	    construct_DR_DRIVE_QUERY_INFORMATION_REQ(&ioreq);
3234
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_QUERY_INFORMATION;
3235
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3236
	    ioreq.DeviceIoRequest.CompletionId = opid;
3237
	    ioreq.DeviceIoRequest.FileId = fhandle;
3238
	    cb->FileId = fhandle;
3239
	    TC_MUTEX_LOCK(&(tmp->lock));
3240
	    tmp->device_id = device_id;
3241
	    tmp->fhandle = fhandle;
3242
	    tmp->uniqid = uniqid;
3243
	    tmp->opid = opid;
3244
	    tmp->opcode = rdpfs_opcode;
3245
	    TC_MUTEX_UNLOCK(&(tmp->lock));
3246
	    MDBGLOG("redir","INFO\t[%s()]: calling GETATTR_ENQ() [g_getattr_q = %p; device_id = %d, fhandle = %d, uniqid = %d, opid = %d]",__func__,g_getattr_q,device_id,fhandle,uniqid,opid);
3247
	    TC_MUTEX_LOCK(mutex_getattr);
3248
	    GETATTR_ENQ(tmp);
3249
	    TC_MUTEX_UNLOCK(mutex_getattr);
3250
	    MDBGLOG("redir","INFO\t[%s()]: GETATTR_ENQ() called. [g_getattr_q = %p]",__func__,g_getattr_q);
3251
	    ioreq.FsInformationClass = FileBasicInformation;
3252
	    send_DR_DRIVE_QUERY_INFORMATION_REQ(&ioreq, r);
3253
	  }
3254
	  break;
3255
	case RDPFS_READLINK:
3256
	  MDBGLOG("redir"," ^^ (RDPFS_READLINK)");
3257
	  break;
3258
	case RDPFS_MKNOD:
3259
	  MDBGLOG("redir"," ^^ (RDPFS_MKNOD)");
3260
	  break;
3261
	case RDPFS_UNLINK:
3262
	  MDBGLOG("redir"," ^^ (RDPFS_UNLINK)");
3263
	  {
3264
	    DR_DRIVE_SET_INFORMATION_REQ ioreq;
3265
	    construct_DR_DRIVE_SET_INFORMATION_REQ(&ioreq);
3266
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
3267
	    TC_MUTEX_LOCK(mutex_client_devicelist);
3268
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3269
	    TC_MUTEX_UNLOCK(mutex_client_devicelist);
3270
	    ioreq.DeviceIoRequest.CompletionId = opid;
3271
	    ioreq.DeviceIoRequest.FileId = fhandle;
3272
	    ioreq.FsInformationClass = FileDispositionInformation;
3273
	    ioreq.Length = 0;
3274
	    send_DR_DRIVE_SET_INFORMATION_REQ(&ioreq, r);
3275
	    MDBGLOG("redir"," ^^ (RDPFS_UNLINK): ioreq.Length = %d; buf = \"%s\"",ioreq.Length,buf);
3276
	  }
3277
	  break;
3278
	case RDPFS_RMDIR:
3279
  	  MDBGLOG("redir"," ^^ (RDPFS_RMDIR)");
3280
	  {
3281
	    DR_DRIVE_SET_INFORMATION_REQ ioreq;
3282
	    construct_DR_DRIVE_SET_INFORMATION_REQ(&ioreq);
3283
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
3284
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3285
	    ioreq.DeviceIoRequest.CompletionId = opid;
3286
	    ioreq.DeviceIoRequest.FileId = fhandle;
3287
	    ioreq.FsInformationClass = FileDispositionInformation;
3288
	    ioreq.Length = 0;
3289
	    send_DR_DRIVE_SET_INFORMATION_REQ(&ioreq, r);
3290
	    MDBGLOG("redir"," ^^ (RDPFS_RMDIR): ioreq.Length = %d; buf = \"%s\"",ioreq.Length,buf);
3291
	  }
3292
	  break;
3293
	case RDPFS_SYMLINK:
3294
	  MDBGLOG("redir"," ^^ (RDPFS_SYMLINK)");
3295
	  break;
3296
	case RDPFS_RENAME:
3297
	  MDBGLOG("redir"," ^^ (RDPFS_RENAME)");
3298
	  {
3299
	    DR_DRIVE_SET_INFORMATION_REQ ioreq;
3300
	    char fpath[512];
3301
	    BYTE wpath[1024];
3302
	    int cnt = 0;
3303
	    char * iptr = NULL;
3304
	    char * optr = NULL;
3305
	    int inum = 0;
3306
	    int onum = 0;
3307
	    size_t tflen = 0;
3308
	    g_memset(&ioreq,0,sizeof(DR_CREATE_REQ));
3309
	    g_memset((char *)fpath,0,sizeof(char)*512);
3310
	    g_memset((BYTE *)wpath,0,sizeof(BYTE)*1024);
3311
	    char * tpos = (char *)NULL;
3312
	    char * tend = (char *)NULL;
3313
	    int diff = 0;
3314
	    fpath_length = g_strlen(buf) + 1;
3315
	    iptr = buf;
3316
	    optr = wpath;
3317
	    inum = fpath_length;
3318
	    onum = 1024;
3319
	    g_outstr(&optr,&onum,&iptr,&inum);
3320
	    cnt = fpath_length * 2;
3321
	    for (idx = 0; idx < cnt; idx++) {
3322
	      if (wpath[idx] == '/') {
3323
		wpath[idx] = '\\';
3324
	      }
3325
	    }
3326
	    construct_DR_DRIVE_SET_INFORMATION_REQ(&ioreq);
3327
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
3328
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3329
	    ioreq.DeviceIoRequest.CompletionId = opid;
3330
	    ioreq.DeviceIoRequest.FileId = fhandle;
3331
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
3332
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
3333
	    ioreq.FsInformationClass = FileRenameInformation;
3334
	    ioreq.SetBuffer.RenameInformation.ReplaceIfExists = 0x01;
3335
	    ioreq.SetBuffer.RenameInformation.RootDirectory = 0x00;
3336
	    ioreq.SetBuffer.RenameInformation.FileNameLength = fpath_length * 2;
3337
	    if (ioreq.SetBuffer.RenameInformation.FileNameLength > 0) {
3338
	      tflen = ioreq.SetBuffer.RenameInformation.FileNameLength;
3339
	      ioreq.SetBuffer.RenameInformation.FileName = (BYTE *)g_malloc(sizeof(BYTE) * (ioreq.SetBuffer.RenameInformation.FileNameLength + 2), 1);
3340
	      g_memcpy(ioreq.SetBuffer.RenameInformation.FileName,wpath,tflen);
3341
	    }
3342
	    ioreq.Length = 6 + ioreq.SetBuffer.RenameInformation.FileNameLength;
3343
	    tpos = r->p;
3344
	    send_DR_DRIVE_SET_INFORMATION_REQ_rename(&ioreq, r);
3345
	    tend = r->p;
3346
	    {
3347
	      int fdx = 0;
3348
	      char tout[1024];
3349
	      g_memset(tout,0,sizeof(char)*1024);
3350
	      for (fdx=0;fdx<ioreq.SetBuffer.RenameInformation.FileNameLength;fdx++) {
3351
		tout[fdx] = ((ioreq.SetBuffer.RenameInformation.FileName)[fdx] == '\0') ? '.' : (ioreq.SetBuffer.RenameInformation.FileName)[fdx];
3352
	      }
3353
	      MDBGLOG("redir"," **** FileNameLength = %d; FileName = %s",ioreq.SetBuffer.RenameInformation.FileNameLength,tout);
3354
	      diff = tend - tpos;
3355
	    }
3356
	    MDBGLOG("redir"," ^^ (RDPFS_RENAME): ioreq.Length = %d; buf = \"%s\"",ioreq.Length,buf);
3357
	  }
3358
	  break;
3359
	case RDPFS_LINK:
3360
	  MDBGLOG("redir"," ^^ (RDPFS_LINK)");
3361
	  break;
3362
	case RDPFS_CHMOD:
3363
	  MDBGLOG("redir"," ^^ (RDPFS_CHMOD)");
3364
	  break;
3365
	case RDPFS_CHOWN:
3366
	  MDBGLOG("redir"," ^^ (RDPFS_CHOWN)");
3367
	  break;
3368
	case RDPFS_IOCTL:
3369
	  MDBGLOG("redir"," ^^ (RDPFS_IOCTL)");
3370
	  break;
3371
	case RDPFS_FSCTL:
3372
	  MDBGLOG("redir"," ^^ (RDPFS_FSCTL)");
3373
	  {
3374
	    DR_CONTROL_REQ fsctlreq;
3375
	    construct_DR_CONTROL_REQ(&fsctlreq);
3376
	    fsctlreq.DeviceIoRequest.DeviceId = device_id;
3377
	    fsctlreq.DeviceIoRequest.CompletionId = opid;
3378
	    fsctlreq.DeviceIoRequest.FileId = fhandle;
3379
	    fsctlreq.DeviceIoRequest.MajorFunction = IRP_MJ_DEVICE_CONTROL;
3380
	    fsctlreq.DeviceIoRequest.MinorFunction = 0x00000000;
3381
	    fsctlreq.InputBufferLength = tinputbufferlength;
3382
	    fsctlreq.OutputBufferLength = toutputbufferlength;
3383
	    fsctlreq.IoControlCode = tcmd;
3384
	    fsctlreq.InputBuffer = tbuffer;
3385
	    send_DR_CONTROL_REQ(&fsctlreq, r);
3386
	  }
3387
	  break;
3388
	case RDPFS_FTRUNCATE:
3389
	case RDPFS_TRUNCATE:
3390
	  if (rdpfs_opcode == RDPFS_FTRUNCATE) {
3391
	    MDBGLOG("redir"," ^^ (RDPFS_FTRUNCATE)");
3392
	  }
3393
	  else {
3394
	    MDBGLOG("redir"," ^^ (RDPFS_TRUNCATE)");
3395
	  }
3396
	  {
3397
	    DR_DRIVE_SET_INFORMATION_REQ ioreq;
3398
	    construct_DR_DRIVE_SET_INFORMATION_REQ(&ioreq);
3399
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3400
	    ioreq.DeviceIoRequest.CompletionId = opid;
3401
	    ioreq.DeviceIoRequest.FileId = fhandle;
3402
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_SET_INFORMATION;
3403
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
3404
	    ioreq.FsInformationClass = FileEndOfFileInformation;
3405
	    ioreq.Length = sizeof(ioreq.SetBuffer.EndOfFileInformation);
3406
	    ioreq.SetBuffer.EndOfFileInformation = toffset;
3407
	    send_DR_DRIVE_SET_INFORMATION_REQ(&ioreq, r);
3408
	  }
3409
	  break;
3410
	case RDPFS_UTIME:
3411
	  MDBGLOG("redir"," ^^ (RDPFS_UTIME)");
3412
	  {
3413
	    DR_DRIVE_QUERY_INFORMATION_REQ ioreq;
3414
	    DECLARE_GETATTR(tmp);
3415
	    construct_DR_DRIVE_QUERY_INFORMATION_REQ(&ioreq);
3416
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_QUERY_INFORMATION;
3417
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3418
	    ioreq.DeviceIoRequest.CompletionId = opid;
3419
	    ioreq.DeviceIoRequest.FileId = fhandle;
3420
	    cb->FileId = fhandle;
3421
	    cb->userdata = (BYTE *)NULL;
3422
	    cb->actime = tactime;
3423
	    cb->modtime = tmodtime;
3424
	    TC_MUTEX_LOCK(&(tmp->lock));
3425
	    tmp->device_id = device_id;
3426
	    tmp->fhandle = fhandle;
3427
	    tmp->uniqid = uniqid;
3428
	    tmp->opcode = rdpfs_opcode;
3429
	    TC_MUTEX_UNLOCK(&(tmp->lock));
3430
	    TC_MUTEX_LOCK(mutex_getattr);
3431
	    GETATTR_ENQ(tmp);
3432
	    TC_MUTEX_UNLOCK(mutex_getattr);
3433
	    ioreq.FsInformationClass = FileBasicInformation;
3434
	    ioreq.Length = sizeof(FILE_BASIC_INFORMATION);
3435
	    send_DR_DRIVE_QUERY_INFORMATION_REQ(&ioreq, r);
3436
	  }
3437
	  break;
3438
	case RDPFS_OPEN:
3439
	  MDBGLOG("redir"," ^^ (RDPFS_OPEN): tflags = 0x%8.8x",tflags);
3440
	  {
3441
	    DR_CREATE_REQ ioreq;
3442
	    char fpath[512];
3443
	    BYTE wpath[1024];
3444
	    int cnt = 0;
3445
	    char * iptr = NULL;
3446
	    char * optr = NULL;
3447
	    int inum = 0;
3448
	    int onum = 0;
3449
	    g_memset(&ioreq,0,sizeof(DR_CREATE_REQ));
3450
	    g_memset((char *)fpath,0,sizeof(char)*512);
3451
	    g_memset((BYTE *)wpath,0,sizeof(BYTE)*1024);
3452
	    fpath_length = g_strlen(buf) + 1;
3453
	    iptr = buf;
3454
	    optr = wpath;
3455
	    inum = fpath_length;
3456
	    onum = 1024;
3457
	    g_outstr(&optr,&onum,&iptr,&inum);
3458
	    cnt = fpath_length * 2;
3459
	    for (idx = 0; idx < cnt; idx++) {
3460
	      if (wpath[idx] == '/') {
3461
		wpath[idx] = '\\';
3462
	      }
3463
	    }
3464
	    pdu = (void *)(&ioreq);
3465
	    construct_DR_CREATE_REQ(&ioreq);
3466
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3467
	    ioreq.DeviceIoRequest.CompletionId = opid;
3468
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
3469
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
3470
	    ioreq.CreateDisposition = FILE_OPEN;
3471
	    ioreq.CreateOptions = toptions;
3472
	    ioreq.DesiredAccess = tflags;
3473
	    ioreq.SharedAccess = tshare;
3474
	    ioreq.FileAttributes = tattributes;
3475
	    ioreq.PathLength = cnt;
3476
	    if (ioreq.PathLength > 2) {
3477
	      g_memcpy((BYTE *)(ioreq.Path),wpath,cnt);
3478
	    }
3479
	    send_DR_CREATE_REQ(&ioreq, r);
3480
	    {
3481
	      int fdx = 0;
3482
	      char tout[1024];
3483
	      g_memset(tout,0,sizeof(char)*1024);
3484
	      for (fdx=0;fdx<ioreq.PathLength;fdx++) {
3485
		tout[fdx] = ((ioreq.Path)[fdx] == '\0') ? '.' : (ioreq.Path)[fdx];
3486
	      }
3487
	      MDBGLOG("redir"," **** PathLength = %d; Path = %s",ioreq.PathLength,tout);
3488
	    }
3489
	    MDBGLOG("redir"," ^^ (RDPFS_OPEN) FileId = %d",ioreq.DeviceIoRequest.FileId);
3490
	  }
3491
	  break;
3492
	case RDPFS_READ:
3493
	  MDBGLOG("redir"," ^^ (RDPFS_READ)");
3494
	  {
3495
	    DR_READ_REQ ioreq;
3496
	    construct_DR_READ_REQ(&ioreq);
3497
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_READ;
3498
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3499
	    ioreq.DeviceIoRequest.CompletionId = opid;
3500
	    ioreq.DeviceIoRequest.FileId = fhandle;
3501
	    cb->opid = opid;
3502
	    cb->FileId = fhandle;
3503
	    ioreq.Length = tsize;
3504
	    ioreq.Offset = toffset;
3505
	    send_DR_READ_REQ(&ioreq, r);
3506
	    MDBGLOG("redir"," ^^ (RDPFS_READ): ioreq.Length = %d; ioreq.Offset = %llu; tsize = %d; toffset = %llu; buf = \"%s\"; ioreq.DeviceIoRequest.DeviceId = %d; ioreq.DeviceIoRequest.FileId = %d; ioreq.DeviceIoRequest.MajorFunction = 0x%8.8x",ioreq.Length,ioreq.Offset,tsize,toffset,buf,ioreq.DeviceIoRequest.DeviceId,ioreq.DeviceIoRequest.FileId,ioreq.DeviceIoRequest.MajorFunction);
3507
	  }
3508
	  break;
3509
        case RDPFS_WRITE:
3510
  	  MDBGLOG("redir"," ^^ (RDPFS_WRITE)");
3511
	  {
3512
	    DR_WRITE_REQ ioreq;
3513
	    construct_DR_WRITE_REQ(&ioreq);
3514
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_WRITE;
3515
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3516
	    ioreq.DeviceIoRequest.CompletionId = opid;
3517
	    ioreq.DeviceIoRequest.FileId = fhandle;
3518
	    ioreq.Length = tsize;
3519
	    ioreq.Offset = toffset;
3520
	    if (ioreq.Length < MAX_STREAM) {
3521
	      if (ioreq.Length > 0) {
3522
		ioreq.WriteData = (BYTE *)g_malloc(sizeof(BYTE) * ioreq.Length, 1);
3523
		in_uint8a(s, ioreq.WriteData, ioreq.Length);
3524
	      }
3525
	    }
3526
	    //MDBGLOG("redir"," ^^ (RDPFS_WRITE): ioreq.WriteData = \"%s\"; ioreq.Length = %d; ioreq.Offset = %d",ioreq.WriteData,ioreq.Length,ioreq.Offset);
3527
	    send_DR_WRITE_REQ(&ioreq, r);
3528
	  }
3529
  	  break;
3530
        case RDPFS_STATFS:
3531
  	  MDBGLOG("redir"," ^^ (RDPFS_STATFS)");
3532
	  {
3533
	    DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ ioreq;
3534
	    construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(&ioreq);
3535
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
3536
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3537
	    ioreq.DeviceIoRequest.CompletionId = opid;
3538
	    ioreq.DeviceIoRequest.FileId = fhandle;
3539
	    ioreq.FsInformationClass = FileFsFullSizeInformation;
3540
	    cb->FileId = fhandle;
3541
	    send_DR_DRIVE_QUERY_VOLUME_INFORMATION_REQ(&ioreq, r);
3542
	  }
3543
  	  break;
3544
        case RDPFS_FLUSH:
3545
  	  MDBGLOG("redir"," ^^ (RDPFS_FLUSH)");
3546
	  {
3547
	    DR_DRIVE_CONTROL_REQ ioreq;
3548
	    construct_DR_DRIVE_CONTROL_REQ(&ioreq);
3549
	    ioreq.Header.DeviceIoRequest.MajorFunction = IRP_MJ_FLUSH_BUFFERS;
3550
	    ioreq.Header.DeviceIoRequest.DeviceId = device_id;
3551
	    ioreq.Header.DeviceIoRequest.CompletionId = opid;
3552
	    ioreq.Header.DeviceIoRequest.FileId = fhandle;
3553
	    cb->FileId = fhandle;
3554
	    send_DR_DRIVE_CONTROL_REQ(&ioreq, r);
3555
	  }
3556
  	  break;
3557
        case RDPFS_RELEASE:
3558
  	  MDBGLOG("redir"," ^^ (RDPFS_RELEASE)");
3559
	  {
3560
	    DR_DRIVE_CLOSE_REQ ioreq;
3561
	    g_memset(&ioreq,0,sizeof(DR_DRIVE_CLOSE_REQ));
3562
	    construct_DR_DRIVE_CLOSE_REQ(&ioreq);
3563
	    ioreq.DeviceCloseRequest.DeviceIoRequest.MajorFunction = IRP_MJ_CLOSE;
3564
	    MDBGLOG("redir","INFO\t[%s()]: about to lock <mutex_client_devicelist>... [%d, %d]",__func__,g_getpid(),g_gettid());
3565
	    TC_MUTEX_LOCK(mutex_client_devicelist);
3566
	    MDBGLOG("redir","INFO\t[%s()]: locked <mutex_client_devicelist>. [%d, %d]",__func__,g_getpid(),g_gettid());
3567
	    MDBGLOG("redir","INFO\t[%s()]: about to lock <mutex_fs_arr>... [%d, %d]",__func__,g_getpid(),g_gettid());
3568
	    TC_MUTEX_LOCK(mutex_fs_arr);
3569
	    MDBGLOG("redir","INFO\t[%s()]: locked <mutex_fs_arr>. [%d, %d]",__func__,g_getpid(),g_gettid());
3570
	    ioreq.DeviceCloseRequest.DeviceIoRequest.DeviceId = device_id;
3571
	    TC_MUTEX_UNLOCK(mutex_fs_arr);
3572
	    MDBGLOG("redir","INFO\t[%s()]: unlocked <mutex_fs_arr>. [%d, %d]",__func__,g_getpid(),g_gettid());
3573
	    TC_MUTEX_UNLOCK(mutex_client_devicelist);
3574
	    MDBGLOG("redir","INFO\t[%s()]: unlocked <mutex_client_devicelist>. [%d, %d]",__func__,g_getpid(),g_gettid());
3575
	    ioreq.DeviceCloseRequest.DeviceIoRequest.FileId = fhandle;
3576
	    ioreq.DeviceCloseRequest.DeviceIoRequest.CompletionId = opid;
3577
	    cb->FileId = fhandle;
3578
	    send_DR_DRIVE_CLOSE_REQ(&ioreq, r);
3579
	    MDBGLOG("redir","filesystem_data_in(): [RDPFS_RELEASE] request sent (FileId = %d)",ioreq.DeviceCloseRequest.DeviceIoRequest.FileId);
3580
	  }
3581
  	  break;
3582
        case RDPFS_FSYNC:
3583
  	  MDBGLOG("redir"," ^^ (RDPFS_FSYNC)");
3584
  	  break;
3585
        case RDPFS_OPENDIR:
3586
	  MDBGLOG("redir"," ^^ (RDPFS_OPENDIR)");
3587
	  {
3588
	    DR_CREATE_REQ ioreq;
3589
	    char fpath[512];
3590
	    BYTE wpath[1024];
3591
	    int cnt = 0;
3592
	    char * iptr = NULL;
3593
	    char * optr = NULL;
3594
	    int inum = 0;
3595
	    int onum = 0;
3596
	    g_memset(&ioreq,0,sizeof(DR_CREATE_REQ));
3597
	    g_memset((char *)fpath,0,sizeof(char)*512);
3598
	    g_memset((BYTE *)wpath,0,sizeof(BYTE)*1024);
3599
	    MDBGLOG("redir"," ^^ (RDPFS_OPENDIR) here 1");
3600
	    fpath_length = g_strlen(buf) + 1;
3601
	    iptr = buf;
3602
	    optr = wpath;
3603
	    inum = fpath_length;
3604
	    onum = 1024;
3605
	    g_outstr(&optr,&onum,&iptr,&inum);
3606
	    cnt = fpath_length * 2;
3607
	    for (idx = 0; idx < cnt; idx++) {
3608
	      if (wpath[idx] == '/') {
3609
		wpath[idx] = '\\';
3610
	      }
3611
	    }
3612
	    pdu = (void *)(&ioreq);
3613
	    construct_DR_CREATE_REQ(&ioreq);
3614
  	    MDBGLOG("redir"," ^^ (RDPFS_OPENDIR) here 5");
3615
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3616
	    ioreq.DeviceIoRequest.CompletionId = opid;
3617
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
3618
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
3619
	    ioreq.CreateDisposition = FILE_OPEN;
3620
//	    ioreq.DesiredAccess = FILE_LIST_DIRECTORY | FILE_TRAVERSE | FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE | FILE_DELETE_CHILD;
3621
//	    ioreq.SharedAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
3622
//	    ioreq.DesiredAccess = FILE_LIST_DIRECTORY | FILE_TRAVERSE;
3623
	    ioreq.DesiredAccess = MAXIMUM_ALLOWED;
3624
	    ioreq.SharedAccess = FILE_SHARE_READ;
3625
	    ioreq.PathLength = cnt;
3626
	    if (ioreq.PathLength > 2) {
3627
	      g_memcpy((BYTE *)(ioreq.Path),wpath,cnt);
3628
	    }
3629
	    send_DR_CREATE_REQ(&ioreq, r);
3630
	    {
3631
	      int fdx = 0;
3632
	      char tout[1024];
3633
	      g_memset(tout,0,sizeof(char)*1024);
3634
	      for (fdx=0;fdx<ioreq.PathLength;fdx++) {
3635
		tout[fdx] = ((ioreq.Path)[fdx] == '\0') ? '.' : (ioreq.Path)[fdx];
3636
	      }
3637
	      MDBGLOG("redir"," **** PathLength = %d; Path = %s",ioreq.PathLength,tout);
3638
	    }
3639
	    MDBGLOG("redir"," ^^ (RDPFS_OPENDIR) FileId = %d",ioreq.DeviceIoRequest.FileId);
3640
	  }
3641
	  break;
3642
        case RDPFS_READDIR:
3643
	  MDBGLOG("redir"," ^^ (RDPFS_READDIR)");
3644
	  {
3645
	    char fpath[512];
3646
	    char wpath[1024];
3647
	    int ps = 0;
3648
	    int cnt = 0;
3649
	    DR_DRIVE_QUERY_DIRECTORY_REQ ioreq;
3650
	    g_memset(&ioreq,0,sizeof(DR_DRIVE_QUERY_DIRECTORY_REQ));
3651
	    g_memset((char *)fpath,0,sizeof(char)*512);
3652
	    g_memset((BYTE *)wpath,0,sizeof(BYTE)*1024);
3653
	    fpath_length = g_strlen(buf);
3654
	    if (fpath_length < 3) {
3655
	      cnt = 6;
3656
	      wpath[0] = '\\';
3657
	      wpath[2] = '*';
3658
	    }
3659
	    else if (fpath_length > 2) {
3660
	      for (idx = 0; idx < fpath_length; idx++) {
3661
		wpath[cnt] = (buf[idx] == '/') ? '\\' : buf[idx];
3662
		cnt += 2;
3663
	      }
3664
	      if (wpath[(cnt - 4)] != '\\' || wpath[(cnt - 2)] == '*') {
3665
		wpath[cnt] = '\\';
3666
		cnt += 2;
3667
		wpath[cnt] = '*';
3668
		cnt += 2;
3669
	      }
3670
	      cnt += 2;	/* corresponds to the final '\0' string terminator */
3671
	    }
3672
	    construct_DR_DRIVE_QUERY_DIRECTORY_REQ(&ioreq);
3673
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
3674
	    ioreq.DeviceIoRequest.MinorFunction = IRP_MN_QUERY_DIRECTORY;
3675
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3676
	    ioreq.DeviceIoRequest.FileId = fhandle;
3677
	    cb->FileId = fhandle;
3678
	    ioreq.DeviceIoRequest.CompletionId = opid;
3679
	    ioreq.FsInformationClass = FileBothDirectoryInformation;
3680
	    ioreq.InitialQuery = 0x01;
3681
	    ioreq.PathLength = cnt;
3682
	    g_memcpy((BYTE *)(ioreq.Path),wpath,ioreq.PathLength);
3683
	    {
3684
	      int fdx = 0;
3685
	      char tout[1024];
3686
	      g_memset(tout,0,sizeof(char)*1024);
3687
	      for (fdx=0;fdx<ioreq.PathLength;fdx++) {
3688
		tout[fdx] = ((ioreq.Path)[fdx] == '\0') ? '.' : (ioreq.Path)[fdx];
3689
	      }
3690
	      MDBGLOG("redir"," **** PathLength = %d; Path = %s",ioreq.PathLength,tout);
3691
	    }
3692
	    send_DR_DRIVE_QUERY_DIRECTORY_REQ(&ioreq, r);
3693
	  }
3694
  	  break;
3695
        case RDPFS_RELEASEDIR:
3696
	  MDBGLOG("redir"," ^^ (RDPFS_RELEASEDIR): fhandle = %d",fhandle);
3697
	  {
3698
	    DR_DRIVE_CLOSE_REQ ioreq;
3699
	    g_memset(&ioreq,0,sizeof(DR_DRIVE_CLOSE_REQ));
3700
	    construct_DR_DRIVE_CLOSE_REQ(&ioreq);
3701
	    ioreq.DeviceCloseRequest.DeviceIoRequest.MajorFunction = IRP_MJ_CLOSE;
3702
	    ioreq.DeviceCloseRequest.DeviceIoRequest.DeviceId = device_id;
3703
	    ioreq.DeviceCloseRequest.DeviceIoRequest.FileId = fhandle;
3704
	    ioreq.DeviceCloseRequest.DeviceIoRequest.CompletionId = opid;
3705
	    cb->FileId = fhandle;
3706
	    send_DR_DRIVE_CLOSE_REQ(&ioreq, r);
3707
	  }
3708
  	  break;
3709
	case RDPFS_FSYNCDIR:
3710
	  MDBGLOG("redir"," ^^ (RDPFS_FSYNCDIR)");
3711
	  break;
3712
	case RDPFS_INIT:
3713
	  MDBGLOG("redir"," ^^ (RDPFS_INIT)");
3714
	  {
3715
	    struct stream * t = (struct stream *)NULL;
3716
	    DR_CREATE_REQ tmp;
3717
	    DR_CREATE_REQ * ioreq = (DR_CREATE_REQ *)NULL;
3718
	    ioreq = &tmp;
3719
	    g_memset(ioreq,0,sizeof(DR_CREATE_REQ));
3720
	    construct_DR_CREATE_REQ(ioreq);
3721
	    ioreq->DeviceIoRequest.DeviceId = device_id;
3722
	    ioreq->DeviceIoRequest.CompletionId = opid;
3723
	    ioreq->PathLength = 2;
3724
//	    ioreq->DesiredAccess = FILE_LIST_DIRECTORY | FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | FILE_TRAVERSE | FILE_DELETE_CHILD;
3725
//	    ioreq->DesiredAccess = FILE_LIST_DIRECTORY | FILE_TRAVERSE;
3726
	    ioreq->DesiredAccess = MAXIMUM_ALLOWED;
3727
	    ioreq->CreateDisposition = FILE_OPEN;
3728
	    ioreq->CreateOptions = FILE_DIRECTORY_FILE;
3729
//	    ioreq->SharedAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
3730
	    ioreq->SharedAccess = FILE_SHARE_READ;
3731
	    ioreq->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
3732
	    send_DR_CREATE_REQ(ioreq, r);
3733
	    // g_hexdump_file("/tmp/taskq_parent_init.hexdump", r->data, (int)(r->p - r->data));
3734
	    cb->CompletionId = opid;
3735
	  }
3736
	  break;
3737
	case RDPFS_DESTROY:
3738
	  MDBGLOG("redir"," ^^ (RDPFS_DESTROY)");
3739
	  {
3740
	    DR_CLOSE_REQ ioreq;
3741
	    construct_DR_CLOSE_REQ(&ioreq);
3742
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3743
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CLOSE;
3744
	    send_DR_CLOSE_REQ(&ioreq, r);
3745
	  }
3746
	  break;
3747
	case RDPFS_ACCESS:
3748
	  MDBGLOG("redir"," ^^ (RDPFS_ACCESS)");
3749
	  break;
3750
	case RDPFS_CREATE:
3751
	  MDBGLOG("redir"," ^^ (RDPFS_CREATE)");
3752
	  {
3753
	    DR_CREATE_REQ ioreq;
3754
	    char fpath[512];
3755
	    BYTE wpath[1024];
3756
	    int cnt = 0;
3757
	    char * iptr = NULL;
3758
	    char * optr = NULL;
3759
	    int inum = 0;
3760
	    int onum = 0;
3761
	    g_memset(&ioreq,0,sizeof(DR_CREATE_REQ));
3762
	    g_memset((char *)fpath,0,sizeof(char)*512);
3763
	    g_memset((BYTE *)wpath,0,sizeof(BYTE)*1024);
3764
	    fpath_length = g_strlen(buf) + 1;
3765
	    iptr = buf;
3766
	    optr = wpath;
3767
	    inum = fpath_length;
3768
	    onum = 1024;
3769
	    g_outstr(&optr,&onum,&iptr,&inum);
3770
	    cnt = fpath_length * 2;
3771
	    for (idx = 0; idx < cnt; idx++) {
3772
	      if (wpath[idx] == '/') {
3773
		wpath[idx] = '\\';
3774
	      }
3775
	    }
3776
	    pdu = (void *)(&ioreq);
3777
	    construct_DR_CREATE_REQ(&ioreq);
3778
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3779
	    ioreq.DeviceIoRequest.CompletionId = opid;
3780
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
3781
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
3782
	    ioreq.CreateDisposition = FILE_CREATE;
3783
	    ioreq.CreateOptions = FILE_NON_DIRECTORY_FILE | toptions;
3784
	    ioreq.DesiredAccess = tflags;
3785
	    ioreq.SharedAccess = tshare;
3786
	    ioreq.FileAttributes = tattributes;
3787
	    ioreq.PathLength = cnt;
3788
	    if (ioreq.PathLength > 2) {
3789
	      g_memcpy((BYTE *)(ioreq.Path),wpath,cnt);
3790
	    }
3791
	    send_DR_CREATE_REQ(&ioreq, r);
3792
	    {
3793
	      int fdx = 0;
3794
	      char tout[1024];
3795
	      g_memset(tout,0,sizeof(char)*1024);
3796
	      for (fdx=0;fdx<ioreq.PathLength;fdx++) {
3797
		tout[fdx] = ((ioreq.Path)[fdx] == '\0') ? '.' : (ioreq.Path)[fdx];
3798
	      }
3799
	      MDBGLOG("redir"," **** PathLength = %d; Path = %s; toptions = 0x%8.8x",ioreq.PathLength,tout,toptions);
3800
	    }
3801
	    MDBGLOG("redir"," ^^ (RDPFS_CREATE) FileId = %d",ioreq.DeviceIoRequest.FileId);
3802
	  }
3803
	  break;
3804
	case RDPFS_MKDIR:
3805
	  MDBGLOG("redir"," ^^ (RDPFS_MKDIR)");
3806
	  {
3807
	    DR_CREATE_REQ ioreq;
3808
	    char fpath[512];
3809
	    BYTE wpath[1024];
3810
	    int cnt = 0;
3811
	    char * iptr = NULL;
3812
	    char * optr = NULL;
3813
	    int inum = 0;
3814
	    int onum = 0;
3815
	    g_memset(&ioreq,0,sizeof(DR_CREATE_REQ));
3816
	    g_memset((char *)fpath,0,sizeof(char)*512);
3817
	    g_memset((BYTE *)wpath,0,sizeof(BYTE)*1024);
3818
	    fpath_length = g_strlen(buf) + 1;
3819
	    iptr = buf;
3820
	    optr = wpath;
3821
	    inum = fpath_length;
3822
	    onum = 1024;
3823
	    g_outstr(&optr,&onum,&iptr,&inum);
3824
	    cnt = fpath_length * 2;
3825
	    for (idx = 0; idx < cnt; idx++) {
3826
	      if (wpath[idx] == '/') {
3827
		wpath[idx] = '\\';
3828
	      }
3829
	    }
3830
	    pdu = (void *)(&ioreq);
3831
	    construct_DR_CREATE_REQ(&ioreq);
3832
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3833
	    ioreq.DeviceIoRequest.CompletionId = opid;
3834
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
3835
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
3836
	    ioreq.CreateDisposition = FILE_CREATE;
3837
	    ioreq.CreateOptions = FILE_DIRECTORY_FILE;
3838
	    ioreq.DesiredAccess = MAXIMUM_ALLOWED;
3839
//	    ioreq.SharedAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
3840
	    ioreq.FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
3841
	    ioreq.PathLength = cnt;
3842
	    if (ioreq.PathLength > 2) {
3843
	      g_memcpy((BYTE *)(ioreq.Path),wpath,cnt);
3844
	    }
3845
	    send_DR_CREATE_REQ(&ioreq, r);
3846
	    {
3847
	      int fdx = 0;
3848
	      char tout[1024];
3849
	      g_memset(tout,0,sizeof(char)*1024);
3850
	      for (fdx=0;fdx<ioreq.PathLength;fdx++) {
3851
		tout[fdx] = ((ioreq.Path)[fdx] == '\0') ? '.' : (ioreq.Path)[fdx];
3852
	      }
3853
	      MDBGLOG("redir"," **** PathLength = %d; Path = %s",ioreq.PathLength,tout);
3854
	    }
3855
	    MDBGLOG("redir"," ^^ (RDPFS_CREATE) FileId = %d",ioreq.DeviceIoRequest.FileId);
3856
	  }
3857
	  break;
3858
	case RDPFS_GETXATTR:
3859
	  MDBGLOG("redir"," ^^ (RDPFS_GETXATTR)");
3860
	  {
3861
	  }
3862
  	  break;
3863
	case RDPFS_SETXATTR:
3864
	  MDBGLOG("redir"," ^^ (RDPFS_SETXATTR)");
3865
	  {
3866
	    DR_DRIVE_SET_INFORMATION_REQ ioreq;
3867
	    g_memset(&ioreq,0,sizeof(DR_DRIVE_SET_INFORMATION_REQ));
3868
	    construct_DR_DRIVE_SET_INFORMATION_REQ(&ioreq);
3869
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3870
	    ioreq.DeviceIoRequest.CompletionId = opid;
3871
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_SET_EA;
3872
	    ioreq.DeviceIoRequest.MinorFunction = 0x00000000;
3873
	    ioreq.FsInformationClass = FileEndOfFileInformation;
3874
	    ioreq.Length = sizeof(ioreq.SetBuffer.EndOfFileInformation);
3875
	    ioreq.SetBuffer.EndOfFileInformation = toffset;
3876
	    send_DR_DRIVE_SET_INFORMATION_REQ(&ioreq, r);
3877
	  }
3878
  	  break;
3879
	case RDPFS_LISTXATTR:
3880
	  MDBGLOG("redir"," ^^ (RDPFS_LISTXATTR)");
3881
	  {
3882
	  }
3883
  	  break;
3884
	case RDPFS_REMOVEXATTR:
3885
	  MDBGLOG("redir"," ^^ (RDPFS_REMOVEXATTR)");
3886
	  {
3887
	  }
3888
  	  break;
3889
	case RDPFS_END:
3890
	  MDBGLOG("redir"," ^^ (RDPFS_END)");
3891
	  {
3892
	    DR_CLOSE_REQ ioreq;
3893
	    construct_DR_CLOSE_REQ(&ioreq);
3894
	    ioreq.DeviceIoRequest.DeviceId = device_id;
3895
	    ioreq.DeviceIoRequest.MajorFunction = IRP_MJ_CLOSE;
3896
	    send_DR_CLOSE_REQ(&ioreq, r);
3897
	  }
3898
  	  break;
3899
        default:
3900
	  MDBGLOG("redir","ERROR\t[%s()]: unrecognized opcode (0x%8.8x)",__func__,rdpfs_opcode);
3901
	  r = trans_get_out_s(trans, MAX_STREAM);
3902
	  magic = RDP_PACKET_MAGIC;
3903
	  size = 0x00000000;
3904
	  crc32 = 0x00000000;
3905
	  rdpfs_opcode |= RDPFS_ERROR;
3906
	  out_uint32_le(r, magic);
3907
	  out_uint32_le(r, rdpfs_opcode);
3908
	  out_uint32_le(r, size);
3909
	  out_uint32_le(r, device_id);
3910
	  out_uint32_le(r, fhandle);
3911
	  out_uint32_le(r, uniqid);
3912
	  out_uint32_le(r, crc32);
3913
	  s_mark_end(r);
3914
	  trans_force_write(trans);
3915
	  r->end = r->data;
3916
	  break;
3917
      }
3918
      /* send the assembled PDU to the RDP client: */
3919
      MDBGLOG("redir","[filesystem_data_in()]: sending PDU to RDP channel...");
3920
      s_mark_end(r);
3921
      size = r->end - r->data;
3922
      if (size > 0) {
3923
	TC_MUTEX_LOCK(mutex_out);
3924
	error = send_channel_data(g_rdpdr_chan_id, r->data, size);
3925
	TC_MUTEX_UNLOCK(mutex_out);
3926
	MDBGLOG("redir","INFO\t[%s()]: sent. (error = %d; g_rdpdr_chan_id = %d)",__func__,error,g_rdpdr_chan_id);
3927
      }
3928
      else {
3929
	MDBGLOG("redir","ERROR\t[%s()]: output PDU is empty (size == 0)",__func__);
3930
      }
3931
    }
3932
    TC_MUTEX_UNLOCK(mutex_cb);
3933
  }
3934
  return error;
3935
}
3936
3937
3938
/*****************************************************************************/
3939
/******		Operation IDs						******/
3940
/*****************************************************************************/
3941
3942
/*****************************************************************************/
3943
static int APP_CC get_opid(void * idev) {
3944
  int rv = 0;
3945
  rdpfs * fs = (rdpfs *)idev;
3946
  if (fs == NULL) {
3947
    rv = -1;
3948
  }
3949
  else {
3950
    if (fs->top_opid == 0) {
3951
      fs->top_opid++;
3952
    }
3953
    rv = fs->top_opid++;
3954
    register_opid(fs, rv);
3955
  }
3956
  return rv;
3957
}
3958
3959
/*****************************************************************************/
3960
static int APP_CC register_opid(void * idev, int opid) {
3961
  int rv = -1;
3962
  int idx = 0;
3963
  int tmp = -1;
3964
  rdpfs * dev = (rdpfs *)idev;
3965
  if (dev == NULL) {
3966
    rv = -1;
3967
  }
3968
  else {
3969
    for (idx = 0; idx < MAX_PENDING; idx++) {
3970
      if ((tmp < 0) && (dev->pending_opids[idx] == 0)) {
3971
	tmp = idx;
3972
	rv = idx;
3973
	dev->pending_opids[idx] = opid;
3974
      }
3975
      else if (dev->pending_opids[idx] == opid) {
3976
	/* ERROR: the opid is already registered */
3977
	rv = -1;
3978
	if (tmp > -1) {
3979
	  dev->pending_opids[tmp] = 0;
3980
	}
3981
	MDBGLOG("redir","ERROR\t[%s()]: \"%d\" is already registered at position %d",__func__,opid,idx);
3982
	break;
3983
      }
3984
    }
3985
  }
3986
  if (rv > -1) {
3987
    if (dev->callbacks != NULL) {
3988
      dev->callbacks[rv].opid = opid;
3989
      dev->callbacks[rv].type = 0;
3990
      dev->callbacks[rv].fs = dev;
3991
      dev->callbacks[rv].fd = dev->parent_sck;
3992
      dev->callbacks[rv].trans = dev->ccon;
3993
    }
3994
    rv = 0;
3995
  }
3996
  return rv;
3997
}
3998
3999
/*****************************************************************************/
4000
static int APP_CC strike_opid(void * idev, int opid) {
4001
  int rv = 0;
4002
  rdpfs * fs = (rdpfs *)idev;
4003
  rv = opid_is_registered(fs, opid);
4004
  if (rv > 0) {
4005
    fs->pending_opids[rv] = 0;
4006
    if (fs->callbacks != NULL) {
4007
      if (fs->callbacks[rv].userdata != NULL && fs->callbacks[rv].length > 0) {
4008
	g_memset(fs->callbacks[rv].userdata,0,fs->callbacks[rv].length);
4009
	//g_free(fs->callbacks[rv].userdata);
4010
	fs->callbacks[rv].userdata = (BYTE *)NULL;
4011
      }
4012
      g_memset(&(fs->callbacks[rv]),0,sizeof(callback));
4013
      //g_free(fs->callbacks[rv]);
4014
      //fs->callbacks[rv] = (callback *)NULL;
4015
    }
4016
  }
4017
  return rv;
4018
}
4019
4020
/*****************************************************************************/
4021
static int APP_CC opid_is_registered(void * idev, int opid) {
4022
  int rv = 0;
4023
  int idx = 0;
4024
  rdpfs * fs = (rdpfs *)idev;
4025
  if (fs == NULL) {
4026
    rv = -1;
4027
  }
4028
  else {
4029
    for (idx = 0; idx < MAX_PENDING; idx++) {
4030
      if (fs->pending_opids[idx] == opid) {
4031
	rv = idx;
4032
	break;
4033
      }
4034
    }
4035
  }
4036
  return rv;
4037
}
4038
4039
/*****************************************************************************/
4040
static int APP_CC
4041
cb_set_data(struct _callback * self, int length, const BYTE * data) {
4042
  int rv = 0;
4043
  return rv;
4044
}
4045
4046
static int APP_CC
4047
cb_set_func(struct _callback * self, void (*func)(struct _rdpfs *, int, tbus, struct trans *, DWORD, DWORD, int, BYTE *)) {
4048
  int rv = 0;
4049
  return rv;
4050
}
4051
4052
static void * APP_CC
4053
cb_call(void * inarg) {
4054
  struct _callback * self = (struct _callback *)inarg;
4055
  if ((self != NULL) && (self->func != NULL)) {
4056
    self->func(
4057
	self->fs,
4058
	self->type,
4059
	self->fd,
4060
	self->trans,
4061
	self->CompletionId,
4062
	self->opcode,
4063
	self->length,
4064
	self->userdata);
4065
  }
4066
  else {
4067
    MDBGLOG("redir","ERROR\t[%s()]: self->func is NULL",__func__);
4068
  }
4069
}
4070
4071
static int APP_CC
4072
cb_call_data(struct _callback * self, int length, const BYTE * data) {
4073
  int rv = 0;
4074
  rv = self->setData(self, length, data);
4075
  if (!rv) {
4076
    self->call(self);
4077
  }
4078
  return rv;
4079
}
4080
4081
static int APP_CC
4082
get_opcode_from_opid(int opid) {
4083
  int rv = -1;
4084
  int i = 0;
4085
  int tmp = 0;
4086
  TC_MUTEX_LOCK(mutex_fs_arr);
4087
  if ((opid > -1) && (g_fs_arr != NULL) && (g_fs_count > 0)) {
4088
    for (i = 0; i < g_fs_count; i++) {
4089
      if (g_fs_arr[i] != NULL) {
4090
	tmp = opid_is_registered(g_fs_arr[i], opid);
4091
	if (tmp > 0) {
4092
	  rv = g_fs_arr[i]->callbacks[tmp].opcode;
4093
	  if (rv > -1) {
4094
	    break;
4095
	  }
4096
	}
4097
      }
4098
    }
4099
  }
4100
  TC_MUTEX_UNLOCK(mutex_fs_arr);
4101
  return rv;
4102
}
4103
4104
static callback * APP_CC
4105
get_callback_from_opid(int opid) {
4106
  callback * rv = (callback *)NULL;
4107
  int i = 0;
4108
  int tmp = 0;
4109
  TC_MUTEX_LOCK(mutex_fs_arr);
4110
  if ((opid > -1) && (g_fs_arr != NULL) && (g_fs_count > 0)) {
4111
    for (i = 0; i < g_fs_count; i++) {
4112
      if (g_fs_arr[i] != NULL) {
4113
	tmp = opid_is_registered(g_fs_arr[i], opid);
4114
	if (tmp > 0) {
4115
	  rv = &(g_fs_arr[i]->callbacks[tmp]);
4116
	  if (rv != NULL) {
4117
	    break;
4118
	  }
4119
	}
4120
      }
4121
    }
4122
  }
4123
  TC_MUTEX_UNLOCK(mutex_fs_arr);
4124
  return rv;
4125
}
4126
4127
static void APP_CC cb_send_buf(struct _rdpfs * fs, int type, tbus fd, struct trans * trans, DWORD CompletionId, DWORD opcode, int length, BYTE * data) {
4128
  int res = 0;
4129
  int fhandle = 0;
4130
  int uniqid = 0;
4131
  uint32_t crc32 = 0x00000000;
4132
  const uint32_t magic = RDP_PACKET_MAGIC;
4133
  uint32_t device_id = 0x00000000;
4134
  struct stream * s = (struct stream *)NULL;
4135
  MDBGLOG("redir","cb_send_buf(): type = %d; fd = %d; CompletionId = %8.8x, opcode = %8.8x, length = %d",type,fd,CompletionId,opcode,length);
4136
  opcode = opcode | RDPFS_REPLY;
4137
  if (type == 1) {
4138
    if (trans == NULL) {
4139
      MDBGLOG("redir","ERROR\t[%s()]: \"trans\" is not a valid transmission channel",__func__);
4140
    }
4141
    else {
4142
      if (length > 0 && data != NULL) {
4143
	crc32 = Crc32_ComputeBuf(0, data, length);
4144
      }
4145
      s = trans_get_out_s(trans, MAX_STREAM);
4146
      out_uint32_le(s, magic);
4147
      out_uint32_le(s, opcode);
4148
      out_uint32_le(s, length);
4149
      out_uint32_le(s, device_id);
4150
      out_uint32_le(s, fhandle);
4151
      out_uint32_le(s, uniqid);
4152
      out_uint32_le(s, crc32);
4153
      if ((length > 0) && (data != NULL)) {
4154
	out_uint8a(s, data, length);
4155
      }
4156
      s_mark_end(s);
4157
      MDBGLOG("redir","INFO\t[%s()]: sending %d bytes to child filesystem handler (\"trans\" mode)",__func__,(int)(s->end - s->data));
4158
      res = trans_force_write(trans);
4159
    }
4160
  }
4161
  else {
4162
    if (length > 0 && data != NULL) {
4163
      crc32 = Crc32_ComputeBuf(0, data, length);
4164
    }
4165
    make_stream(s);
4166
    init_stream(s, MAX_STREAM);
4167
    out_uint32_le(s, magic);
4168
    out_uint32_le(s, opcode);
4169
    out_uint32_le(s, length);
4170
    out_uint32_le(s, device_id);
4171
    out_uint32_le(s, fhandle);
4172
    out_uint32_le(s, uniqid);
4173
    out_uint32_le(s, crc32);
4174
    if ((length > 0) && (data != NULL)) {
4175
      out_uint8a(s, data, length);
4176
    }
4177
    s_mark_end(s);
4178
    if (fd > 0) {
4179
      MDBGLOG("redir","INFO\t[%s()]: sending %d bytes to child filesystem handler (\"non-trans\" mode)",__func__,(int)(s->end - s->data));
4180
      res = g_tcp_send(fd, s->data, (int)(s->end - s->data), 0);
4181
    }
4182
    else {
4183
      MDBGLOG("redir","ERROR\t[%s()]: fd is not a valid file descriptor (fd = %d)",__func__,fd);
4184
    }
4185
  }
4186
  //free_stream(s);
4187
}
4188
4189
static void APP_CC cb_send_bare(struct _rdpfs * fs, int type, tbus fd, struct trans * trans, DWORD CompletionId, DWORD opcode, int length, BYTE * data) {
4190
  int res = 0;
4191
  int fhandle = 0;
4192
  int uniqid = 0;
4193
  uint32_t crc32 = 0x00000000;
4194
  const uint32_t magic = RDP_PACKET_MAGIC;
4195
  uint32_t device_id = 0x00000000;
4196
  struct stream * s = (struct stream *)NULL;
4197
  MDBGLOG("redir","cb_send_bare(): type = %d; fd = %d; CompletionId = %8.8x, opcode = %8.8x, length = %d",type,fd,CompletionId,opcode,length);
4198
  opcode = RDPFS_REPLY;
4199
  if (type == 1) {
4200
    if (trans == NULL) {
4201
      MDBGLOG("redir","ERROR [cb_send_buf()]: \"trans\" is not a valid transmission channel");
4202
    }
4203
    else {
4204
      if (length > 0 && data != NULL) {
4205
	crc32 = Crc32_ComputeBuf(0, data, length);
4206
      }
4207
      s = trans_get_out_s(trans, MAX_STREAM);
4208
      out_uint32_le(s, magic);
4209
      out_uint32_le(s, opcode);
4210
      out_uint32_le(s, length);
4211
      out_uint32_le(s, device_id);
4212
      out_uint32_le(s, fhandle);
4213
      out_uint32_le(s, uniqid);
4214
      out_uint32_le(s, crc32);
4215
      if ((length > 0) && (data != NULL)) {
4216
        out_uint8a(s, data, length);
4217
      }
4218
      s_mark_end(s);
4219
      MDBGLOG("redir","cb_send_buf(): sending %d bytes to child filesystem handler (\"trans\" mode)",(int)(s->end - s->data));
4220
      res = trans_force_write(trans);
4221
    }
4222
  }
4223
  else {
4224
    if (length > 0 && data != NULL) {
4225
      crc32 = Crc32_ComputeBuf(0, data, length);
4226
    }
4227
    make_stream(s);
4228
    init_stream(s, MAX_STREAM);
4229
    out_uint32_le(s, magic);
4230
    out_uint32_le(s, opcode);
4231
    out_uint32_le(s, length);
4232
    out_uint32_le(s, device_id);
4233
    out_uint32_le(s, fhandle);
4234
    out_uint32_le(s, uniqid);
4235
    out_uint32_le(s, crc32);
4236
    if ((length > 0) && (data != NULL)) {
4237
      out_uint8a(s, data, length);
4238
    }
4239
    s_mark_end(s);
4240
    if (fd > 0) {
4241
      MDBGLOG("redir","cb_send_buf(): sending %d bytes to child filesystem handler (\"non-trans\" mode)",(int)(s->end - s->data));
4242
      res = g_tcp_send(fd, s->data, (int)(s->end - s->data), 0);
4243
    }
4244
    else {
4245
      MDBGLOG("redir","ERROR [cb_send_buf()]: fd is not a valid file descriptor (fd = %d)",fd);
4246
    }
4247
  }
4248
  //free_stream(s);
4249
}
4250
4251
/***/
4252
char * APP_CC ntstatus_string(uint32_t ival) {
4253
  char * rv = (char *)NULL;
4254
  int idx = 0;
4255
  int lmt = 0;
4256
4257
  lmt = sizeof(NT_errors) / sizeof(value_string);
4258
  for (idx = 0; idx < lmt; idx++) {
4259
    if (NT_errors[idx].value == ival) {
4260
      rv = (char *)NT_errors[idx].strptr;
4261
      break;
4262
    }
4263
  }
4264
4265
  return rv;
4266
}
4267
4268
void test_serial_port(int device_id) {
4269
  int lfd = 0;
4270
  lfd = open("/tmp/testfifo", O_WRONLY);
4271
  if (lfd > 0) {
4272
    char lbuf[6] = {'a','b','c','d','e',0};
4273
    g_fifo_write(lfd,lbuf,5);
4274
    close(lfd);
4275
  }
4276
  else {
4277
    MDBGLOG("redir","no good :(");
4278
  }
4279
}
4280
4281
void test_serial_port_old(int device_id) {
4282
  char rdata[MAX_STREAM];
4283
  DR_PORT_CREATE_REQ lreq;
4284
  DR_PORT_CREATE_REQ * req = &lreq;
4285
  struct stream rs;
4286
  struct stream * r = &rs;
4287
  size_t size = 0;
4288
4289
  g_memset(rdata,0,sizeof(char)*MAX_STREAM);
4290
  r->data = rdata;
4291
  r->p = r->data;
4292
  r->end = r->data;
4293
  r->size = MAX_STREAM;
4294
4295
  construct_DR_CREATE_REQ(req);
4296
  req->DeviceIoRequest.DeviceId = device_id;
4297
  req->DeviceIoRequest.MajorFunction = IRP_MJ_CREATE;
4298
  req->DeviceIoRequest.CompletionId = 7;
4299
  req->DesiredAccess = 0x00100080;
4300
  req->SharedAccess = 0x00000007;
4301
  req->CreateDisposition = 0x00000001;
4302
  req->CreateOptions = 0x00000060;
4303
4304
  send_DR_CREATE_REQ(req, r);
4305
4306
  s_mark_end(r);
4307
  size = r->end - r->data;
4308
4309
  if (size > 0) {
4310
    TC_MUTEX_LOCK(mutex_out);
4311
    send_channel_data(g_rdpdr_chan_id, r->data, size);
4312
    TC_MUTEX_UNLOCK(mutex_out);
4313
  }
4314
}
4315
4316
static inline int APP_CC is_filesystem(int device_idx) {
4317
    if (TC_MUTEX_TRYLOCK(mutex_client_devicelist) == 0) {
4318
      if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4319
        TC_MUTEX_UNLOCK(mutex_client_devicelist);
4320
        return 0;
4321
      }
4322
      else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_FILESYSTEM) {
4323
        TC_MUTEX_UNLOCK(mutex_client_devicelist);
4324
        return 1;
4325
      }
4326
      else {
4327
        TC_MUTEX_UNLOCK(mutex_client_devicelist);
4328
        return 0;
4329
      }
4330
    }
4331
    else {
4332
      if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4333
        return 0;
4334
      }
4335
      else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_FILESYSTEM) {
4336
        return 1;
4337
      }
4338
      else {
4339
        return 0;
4340
      }
4341
    }
4342
}
4343
4344
static inline int APP_CC is_port(int device_idx) {
4345
  if (TC_MUTEX_TRYLOCK(mutex_client_devicelist) == 0) {
4346
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4347
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4348
      return 0;
4349
    }
4350
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_SERIAL || g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_PARALLEL) {
4351
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4352
      return 1;
4353
    }
4354
    else {
4355
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4356
      return 0;
4357
    }
4358
  }
4359
  else {
4360
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4361
      return 0;
4362
    }
4363
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_SERIAL || g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_PARALLEL) {
4364
      return 1;
4365
    }
4366
    else {
4367
      return 0;
4368
    }
4369
  }
4370
}
4371
4372
static inline int APP_CC is_serial(int device_idx) {
4373
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4374
      return 0;
4375
    }
4376
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_SERIAL) {
4377
      return 1;
4378
    }
4379
    else {
4380
      return 0;
4381
    }
4382
}
4383
4384
static inline int APP_CC is_parallel(int device_idx) {
4385
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4386
      return 0;
4387
    }
4388
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_PARALLEL) {
4389
      return 1;
4390
    }
4391
    else {
4392
      return 0;
4393
    }
4394
}
4395
4396
static inline int APP_CC is_printer(int device_idx) {
4397
  if (TC_MUTEX_TRYLOCK(mutex_client_devicelist) == 0) {
4398
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4399
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4400
      return 0;
4401
    }
4402
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_PRINT) {
4403
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4404
      return 1;
4405
    }
4406
    else {
4407
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4408
      return 0;
4409
    }
4410
  }
4411
  else {
4412
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4413
      return 0;
4414
    }
4415
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_PRINT) {
4416
      return 1;
4417
    }
4418
    else {
4419
      return 0;
4420
    }
4421
  }
4422
}
4423
4424
static inline int APP_CC is_smartcard(int device_idx) {
4425
  if (TC_MUTEX_TRYLOCK(mutex_client_devicelist) == 0) {
4426
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4427
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4428
      return 0;
4429
    }
4430
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_SMARTCARD) {
4431
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4432
      return 1;
4433
    }
4434
    else {
4435
      TC_MUTEX_UNLOCK(mutex_client_devicelist);
4436
      return 0;
4437
    }
4438
  }
4439
  else {
4440
    if (device_idx < 0 || g_client_devicelist == NULL || device_idx > g_client_devicelist->DeviceCount || g_client_devicelist->DeviceList[device_idx] == NULL) {
4441
      return 0;
4442
    }
4443
    else if (g_client_devicelist->DeviceList[device_idx]->DeviceType == RDPDR_DTYP_SMARTCARD) {
4444
      return 1;
4445
    }
4446
    else {
4447
      return 0;
4448
    }
4449
  }
4450
}
4451
4452
static APP_CC int get_device_index(int DeviceId) {
4453
  int rv = -1;
4454
  int idx = 0;
4455
4456
  if (TC_MUTEX_TRYLOCK(mutex_client_devicelist) == 0) {
4457
    if (DeviceId < 0 || g_client_devicelist == NULL || g_client_devicelist->DeviceList == NULL || g_client_devicelist->DeviceCount < 1) {
4458
      rv = -1;
4459
    }
4460
    else for (idx = 0; idx < g_client_devicelist->DeviceCount; idx ++) {
4461
      if (g_client_devicelist->DeviceList[idx] != NULL && g_client_devicelist->DeviceList[idx]->DeviceId == DeviceId) {
4462
        rv = idx;
4463
        break;
4464
      }
4465
    }
4466
    TC_MUTEX_UNLOCK(mutex_client_devicelist);
4467
  }
4468
  else {
4469
    if (DeviceId < 0 || g_client_devicelist == NULL || g_client_devicelist->DeviceList == NULL || g_client_devicelist->DeviceCount < 1) {
4470
      rv = -1;
4471
    }
4472
    else for (idx = 0; idx < g_client_devicelist->DeviceCount; idx ++) {
4473
      if (g_client_devicelist->DeviceList[idx] != NULL && g_client_devicelist->DeviceList[idx]->DeviceId == DeviceId) {
4474
        rv = idx;
4475
        break;
4476
      }
4477
    }
4478
  }
4479
4480
  return rv;
60
}
4481
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/devredir.h (-5 / +8 lines)
 Lines 2-20    Link Here 
2
#if !defined(DEVREDIR_H)
2
#if !defined(DEVREDIR_H)
3
#define DEVREDIR_H
3
#define DEVREDIR_H
4
4
5
#include <stdint.h>
6
#include "defines.h"
7
#include "ntstatus.h"
5
#include "arch.h"
8
#include "arch.h"
6
#include "parse.h"
9
#include "parse.h"
7
10
8
int APP_CC
11
int APP_CC
9
dev_redir_init(void);
12
rdpdr_init(void);
10
int APP_CC
13
int APP_CC
11
dev_redir_deinit(void);
14
rdpdr_deinit(void);
12
int APP_CC
15
int APP_CC
13
dev_redir_data_in(struct stream* s, int chan_id, int chan_flags, int length,
16
rdpdr_data_in(struct stream* s, int chan_id, int chan_flags, int length,
14
                  int total_length);
17
                  int total_length);
15
int APP_CC
18
int APP_CC
16
dev_redir_get_wait_objs(tbus* objs, int* count, int* timeout);
19
rdpdr_get_wait_objs(tbus* objs, int* count, int* timeout);
17
int APP_CC
20
int APP_CC
18
dev_redir_check_wait_objs(void);
21
rdpdr_check_wait_objs(void);
19
22
20
#endif
23
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/drdynvc.c (+1647 lines)
Line 0    Link Here 
1
/*
2
   This program is free software; you can redistribute it and/or modify
3
   it under the terms of the GNU General Public License as published by
4
   the Free Software Foundation; either version 2 of the License, or
5
   (at your option) any later version.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15
16
   xrdp: A Remote Desktop Protocol server.
17
   Copyright (C) Jay Sorg 2009
18
*/
19
20
#include <pthread.h>
21
#include <stddef.h>
22
#include <stdint.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
27
#include "arch.h"
28
#include "chansrv.h"
29
#include "defines.h"
30
#include "drdynvc_defs.h"
31
#include "drdynvc.h"
32
#include "rdpdr.h"
33
#include "rdpdr_methods.h"
34
#include "os_calls.h"
35
#include "parse.h"
36
#include "trans.h"
37
#include "thread_calls.h"
38
#include "thread_macros.h"
39
#include "nterrmsg.h"
40
#include "crc32.h"
41
42
#include "dbg.h"
43
44
#if defined(MDBGLOG)
45
#undef MDBGLOG
46
#define MDBGLOG(...)	;
47
#endif
48
49
#define RDPEDYC_NEW	RDPDR_NEW
50
51
#ifndef MAX_PENDING
52
#define MAX_PENDING 512
53
#endif
54
55
#ifndef WO_PATH
56
#define WO_PATH		"xrdp_chansrv_drdynvc"
57
#endif
58
59
static inline const char * nterr_msg(uint32_t);
60
61
//static const unsigned int g_drdynvc_socket_type = WO_INET;	/* 1: PF_INET/PF_INET6; 2: PF_UNIX; 3: FIFO (named pipe)	*/
62
static const unsigned int g_drdynvc_socket_type = WO_LOCAL;	/* 1: PF_INET/PF_INET6; 2: PF_UNIX; 3: FIFO (named pipe)	*/
63
//static const unsigned int g_drdynvc_socket_type = WO_FIFO;	/* 1: PF_INET/PF_INET6; 2: PF_UNIX; 3: FIFO (named pipe)	*/
64
65
static drdynvc_list_t *	g_channel_list = (drdynvc_list_t *)NULL;
66
67
static tc_t		g_create_thread;
68
static tc_p		thread_create = &g_create_thread;
69
70
tc_p			mutex_channel_list = (tc_p)NULL;
71
static tc_t		g_channel_list_mutex;
72
static tc_t		g_drdynvc_arr_mutex;
73
static tc_p		mutex_drdynvc_arr = (tc_p)NULL;
74
75
static tc_t		g_cb_mutex;
76
static tc_p		mutex_cb = (tc_p)NULL;
77
78
static tc_t		g_server_thread;
79
static tc_p		thread_server = &g_server_thread;
80
81
static tc_t		g_data_thread;
82
static tc_p		thread_data = &g_data_thread;
83
static tc_t		g_data_cond;
84
static tc_p		cond_data = (tc_p)NULL;
85
static tc_t		g_data_mutex;
86
static tc_p		mutex_data = (tc_p)NULL;
87
static tc_t		g_close_mutex;
88
static tc_p		mutex_close = (tc_p)NULL;
89
static tc_t		g_id_mutex;
90
static tc_p		mutex_id = (tc_p)NULL;
91
92
static tc_t		g_done_mutex;
93
static tc_p		mutex_done = (tc_p)NULL;
94
95
static unsigned char	g_is_child			= 0;
96
static ptrdiff_t	g_idx				= 0;
97
98
static tbus *		g_sck_arr			= (tbus *)NULL;
99
static ptrdiff_t	g_sck_count			= 0;
100
101
static unsigned char	g_done				= 0;
102
static unsigned char	g_drdynvc_up			= 0;
103
static tbus		g_drdynvc_wait_obj		= -1;
104
static tbus		g_sck				= -1;
105
static struct stream *	g_ins				= (struct stream *)NULL;
106
static unsigned char	g_client_announce_reply_received = 0;
107
static int		g_client_id			= 0x0001;
108
static rdpchan_t **	g_drdynvc_arr			= (rdpchan_t **)NULL;
109
ptrdiff_t		g_drdynvc_count			= 0;
110
static ptrdiff_t	g_data_in_progress[MAX_CHANNEL];
111
static ptrdiff_t	g_opid				= 5;
112
static callback_t	g_callbacks[MAX_PENDING];
113
static ptrdiff_t	g_pending_operations[MAX_PENDING];
114
static tbus		g_channel_ids[MAX_CHANNEL];
115
116
/* static struct config_sesman * g_cfg = (struct config_sesman *)NULL; */
117
118
static ptrdiff_t APP_CC get_opid(void *);
119
static ptrdiff_t APP_CC register_opid(void *, ptrdiff_t);
120
static ptrdiff_t APP_CC strike_opid(void *, ptrdiff_t);
121
static int APP_CC opid_is_registered(void *, ptrdiff_t);
122
static ptrdiff_t APP_CC get_opcode_from_opid(ptrdiff_t);
123
static callback * APP_CC get_callback_from_opid(ptrdiff_t);
124
125
static ptrdiff_t APP_CC reserve_channel_id(void);
126
static int APP_CC release_channel_id(ptrdiff_t);
127
128
static int APP_CC drdynvc_handle_connection(tbus);
129
130
static int APP_CC drdynvc_output_DYNVC_CREATE_REQ(struct stream *, int, const char *);
131
static int APP_CC drdynvc_process_CAPABILITIES_RSP(struct stream *);
132
static int APP_CC drdynvc_process_CREATE_RSP(struct stream *, rdpchan_t *);
133
static int APP_CC drdynvc_process_DATA_FIRST(struct stream *, rdpchan_t *);
134
static int APP_CC drdynvc_process_DATA(struct stream *, rdpchan_t *);
135
static int APP_CC drdynvc_process_CLOSE(struct stream *);
136
137
static inline drdynvc_t * APP_CC get_channel(DWORD);
138
139
static char * APP_CC ucs2ascii(const uint8_t *);
140
141
static void * APP_CC drdynvc_data_loop(void *);
142
static void * APP_CC drdynvc_create_loop(void *);
143
static void * APP_CC drdynvc_server_loop(void *);
144
static ptrdiff_t APP_CC drdynvc_child_loop(ptrdiff_t);
145
static size_t APP_CC app_data_in(struct trans *);
146
147
static ptrdiff_t APP_CC register_opid(void *, ptrdiff_t);
148
static ptrdiff_t APP_CC strike_opid(void *, ptrdiff_t);
149
static int APP_CC opid_is_registered(void *, ptrdiff_t);
150
static ptrdiff_t APP_CC get_opcode_from_opid(ptrdiff_t);
151
static ptrdiff_t APP_CC get_channel_index(ptrdiff_t);
152
153
static tc_mut_t g_drdynvc_mutex;
154
static tc_p drdynvc_mut = (tc_p)NULL;
155
156
extern tc_t		g_out_mutex;
157
extern tc_p		mutex_out;
158
extern int		g_drdynvc_chan_id;				/* in chansrv.c */
159
160
/*****************************************************************************/
161
int APP_CC
162
drdynvc_init(void) {
163
  int rv = 0;
164
  int pid = 0;
165
  char wo_fpath[512] = "";
166
  tbus lpid = -1;
167
  tbus pid_handler = -1;
168
  tbus pid_sndin = -1;
169
  char dpath[64] = "";
170
  char apath[64] = "";
171
172
  MDBGLOG("drdynvc","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
173
174
  drdynvc_mut = (tc_p)&g_drdynvc_mutex;
175
  tc_mutex_init(drdynvc_mut,NULL);
176
177
  {
178
    tc_t mattr;
179
    tc_p pattr = &mattr;
180
    tc_t nattr;
181
    tc_p pnattr = &nattr;
182
    tc_t rattr;
183
    tc_p sattr = &rattr;
184
    TC_CONDATTR_INIT(sattr);
185
    TC_CONDATTR_SETPSHARED(sattr, TC_PROCESS_PRIVATE);
186
    TC_MUTATTR_INIT(pattr);
187
    TC_MUTATTR_SETTYPE(pattr, TC_MUTEX_ERRORCHECK);
188
    TC_MUTATTR_SETPSHARED(pattr, TC_PROCESS_SHARED);
189
    TC_MUTATTR_INIT(pnattr);
190
    TC_MUTATTR_SETTYPE(pnattr, TC_MUTEX_ERRORCHECK);
191
    TC_MUTATTR_SETPSHARED(pnattr, TC_PROCESS_PRIVATE);
192
    mutex_channel_list = &g_channel_list_mutex;
193
    TC_MUTEX_INIT(mutex_channel_list, pattr);
194
    mutex_drdynvc_arr = &g_drdynvc_arr_mutex;
195
    TC_MUTEX_INIT(mutex_drdynvc_arr, pattr);
196
    mutex_data = &g_data_mutex;
197
    TC_MUTEX_INIT(mutex_data, pattr);
198
    mutex_cb = &g_cb_mutex;
199
    TC_MUTEX_INIT(mutex_cb, pattr);
200
    mutex_done = &g_done_mutex;
201
    TC_MUTEX_INIT(mutex_done, pattr);
202
    mutex_close = &g_close_mutex;
203
    TC_MUTEX_INIT(mutex_close, pattr);
204
    mutex_id = &g_id_mutex;
205
    TC_MUTEX_INIT(mutex_id, pattr);
206
    cond_data = &g_data_cond;
207
    TC_COND_CREATE(cond_data, sattr);
208
  }
209
210
  g_memset(wo_fpath,0,sizeof(char) * 512);
211
  TC_MUTEX_LOCK(mutex_cb);
212
  g_memset((callback_t *)g_callbacks,0,sizeof(callback_t) * MAX_PENDING);
213
  TC_MUTEX_UNLOCK(mutex_cb);
214
  TC_MUTEX_LOCK(mutex_id);
215
  g_memset(g_channel_ids,0,sizeof(g_channel_ids));
216
  TC_MUTEX_UNLOCK(mutex_id);
217
218
  if (g_drdynvc_up)
219
  {
220
    MDBGLOG("drdynvc","INFO\t[%s()]: g_drdynvc already equals 1",__func__);
221
    return 0;
222
  }
223
  drdynvc_deinit();
224
225
  /* g_cfg = (struct config_sesman *)g_malloc(sizeof(struct config_sesman), 1); */
226
  /* config_read(g_cfg); */
227
228
  TC_MUTEX_LOCK(mutex_data);
229
  g_memset(g_data_in_progress,0,sizeof(g_data_in_progress));
230
  TC_MUTEX_UNLOCK(mutex_data);
231
232
  /* Ascertain the PID of this process, for incorporating into the filename */
233
  pid = g_getpid();
234
235
  /* Construct path and filename for the wait object */
236
  g_snprintf(wo_fpath,511,WO_PATH,pid);
237
238
  /* Create wait object */
239
  if (g_drdynvc_socket_type == WO_LOCAL || g_drdynvc_socket_type == WO_INET) {
240
    g_drdynvc_wait_obj = g_create_wait_obj(wo_fpath);
241
  }
242
  else if (g_drdynvc_socket_type == WO_FIFO) {
243
    tbus fifo_fd = -1;
244
    fifo_fd = g_create_fifo(wo_fpath);
245
    if (fifo_fd < 1) {
246
      MDBGLOG("drdynvc","ERROR\t[%s()]: failed to create FIFO for wait object",__func__);
247
    }
248
    else {
249
      g_drdynvc_wait_obj = g_create_wait_obj_from_fifo(fifo_fd, 0);
250
    }
251
  }
252
253
  if (rv == 0) {
254
    g_drdynvc_up = 1;
255
    make_stream(g_ins);
256
    init_stream(g_ins, MAX_STREAM);
257
  }
258
  else
259
  {
260
    MDBGLOG("drdynvc","ERROR\t[%s()]: error on exit",__func__);
261
  }
262
263
  MDBGLOG("drdynvc","INFO\t[%s()]: g_drdynvc_chan_id = %d",__func__,g_drdynvc_chan_id);
264
  if (rv != 0)
265
  {
266
      MDBGLOG("drdynvc","INFO\t[%s()]: send_channel_data failed (rv = %d)", __func__, rv);
267
      rv = 4;
268
  }
269
270
  lpid = g_getpid();
271
272
  {
273
    tbus tsck = -1;
274
    if (g_drdynvc_socket_type == WO_INET) {
275
      tsck = g_tcp_socket();
276
      g_tcp_set_non_blocking(tsck);
277
      if (tsck > 0 && !g_tcp_bind_flags(tsck, "7712", AI_ADDRCONFIG | AI_PASSIVE)) {
278
	TC_MUTEX_LOCK(mutex_channel_list);
279
	g_tcp_listen(tsck);
280
	g_sck = g_create_wait_obj_from_socket(tsck, 1);
281
	TC_MUTEX_UNLOCK(mutex_channel_list);
282
      }
283
    }
284
    else if (g_drdynvc_socket_type == WO_LOCAL) {
285
      int res = 0;
286
      tsck = g_tcp_local_socket();
287
      if (tsck > 0) {
288
	g_snprintf(dpath, sizeof(dpath), "%s/xrdp/.xrdp_drdynvc_sock_%d", XRDP_PID_PATH, lpid);
289
	res = g_tcp_local_bind(tsck, dpath);
290
      }
291
      if (tsck < 1 || res != 0) {
292
	MDBGLOG("drdynvc","ERROR\t[%s()]: failed to bind \"%s\" (tsck = %d, res = %d)",__func__,dpath,tsck,res);
293
	TC_MUTEX_LOCK(mutex_close);
294
	g_done = 1;
295
	TC_MUTEX_UNLOCK(mutex_close);
296
	return 0;
297
      }
298
      else {
299
	TC_MUTEX_LOCK(mutex_channel_list);
300
	g_tcp_listen(tsck);
301
	g_sck = g_create_wait_obj_from_socket(tsck, 1);
302
	TC_MUTEX_UNLOCK(mutex_channel_list);
303
      }
304
    }
305
    else if (g_drdynvc_socket_type == WO_FIFO) {
306
      g_snprintf(dpath, sizeof(dpath), "%s/xrdp/.xrdp_drdynvc_sock_%d", XRDP_PID_PATH, lpid);
307
      g_create_fifo(dpath);
308
      tsck = g_fifo_open(dpath);
309
      if (tsck > 0) {
310
	//TC_MUTEX_LOCK(mutex_channel_list);
311
	//g_sck = g_create_wait_object_from_fifo(tsck, 0);
312
	//TC_MUTEX_UNLOCK(mutex_channel_list);
313
      }
314
    }
315
    if (g_sck > 0) {
316
    }
317
  }
318
319
  TC_THREAD_INIT(&(thread_data->thread), drdynvc_data_loop, NULL);
320
  TC_THREAD_INIT(&(thread_create->thread), drdynvc_create_loop, NULL);
321
  //TC_THREAD_INIT(&(thread_server->thread), drdynvc_server_loop, NULL);
322
323
  if ((pid_handler = g_fork()) < 0) {
324
    MDBGLOG("drdynvc","ERROR\t[%s()]: g_fork() failed (pid_handler = %d)",__func__,pid_handler);
325
    rv = -1;
326
    goto end;
327
  }
328
  else if (pid_handler == 0) {	/* child */
329
    tbus hpid = -1;
330
    hpid = g_getpid();
331
    g_snprintf(apath, sizeof(apath), "%s/xrdp/audio_interface_socket_%d", XRDP_PID_PATH, hpid);
332
    if ((pid_sndin = g_fork()) < 0) {
333
      MDBGLOG("drdynvc","ERROR\t[%s()]: g_fork() failed (pid_sndin = %d)",__func__,pid_sndin);
334
      rv = -1;
335
      goto end;
336
    }
337
    else if (pid_sndin == 0) {
338
      unsigned char lcnt = 0;
339
      char * cargs[] = { "xrdp_rdpeai", apath, (char *)NULL };
340
      char exe_path[256] = "";
341
      g_memset(exe_path,0,sizeof(exe_path));
342
      g_snprintf(exe_path, sizeof(exe_path), "%s/xrdp_rdpeai", XRDP_SBIN_PATH);
343
      if (g_strlen(apath) > 0) while (!g_file_exist(apath) && lcnt < 11) {
344
	lcnt++;
345
	g_sleep(600);
346
      }
347
      if (g_strlen(apath) > 0 && lcnt < 10) {
348
	if (g_strlen(exe_path) > 0) {
349
	  MDBGLOG("drdynvc","INFO\t[%s()]: launching \"%s(%s)\"...",__func__,exe_path,apath);
350
	  g_execvp(exe_path, cargs);
351
	  MDBGLOG("drdynvc","ERROR\t[%s()]: g_execvp() failed (exe_path = %s)",__func__,exe_path);
352
	  rv = -1;
353
	}
354
	else {
355
	  MDBGLOG("drdynvc","ERROR\t[%s()]: exe_path does not exist (exe_path = \"%s\")",__func__,exe_path);
356
	  rv = -1;
357
	}
358
      }
359
      else {
360
	MDBGLOG("drdynvc","ERROR\t[%s()]: socket file does not exist (apath = \"%s\")",__func__,apath);
361
	rv = -1;
362
      }
363
    }
364
    else {
365
      char * cargs[] = { "xrdp_drdynvc_interface", dpath, apath, (char *)NULL };
366
      char exe_path[256] = "";
367
      g_memset(exe_path,0,sizeof(exe_path));
368
      g_snprintf(exe_path, sizeof(exe_path), "%s/xrdp_drdynvc_interface", XRDP_SBIN_PATH);
369
      if (g_strlen(exe_path) > 0) {
370
	MDBGLOG("drdynvc","INFO\t[%s()]: launching \"%s(%s, %s)\"...",__func__,exe_path,dpath,apath);
371
	g_execvp(exe_path, cargs);
372
	MDBGLOG("drdynvc","ERROR\t[%s()]: g_execvp() failed (exe_path = %s)",__func__,exe_path);
373
	rv = -1;
374
      }
375
      else {
376
	MDBGLOG("drdynvc","ERROR\t[%s()]: exe_path does not exist (exe_path = \"%s\")",__func__,exe_path);
377
	rv = -1;
378
      }
379
    }
380
  }
381
 end:;
382
  return rv;
383
}
384
385
/*****************************************************************************/
386
void * APP_CC
387
drdynvc_create_loop(void * arg) {
388
    void * rv = (void *)NULL;
389
    ptrdiff_t size = 0;
390
    DYNVC_CAPS_VERSION2 * pdu = (DYNVC_CAPS_VERSION2 *)NULL;
391
    LOCAL_STREAM(s);
392
    LOCAL_STREAM(ts);
393
394
    pdu = RDPEDYC_NEW(DYNVC_CAPS_VERSION2);
395
    pdu->Version = DRDYNVC_VERSION2;
396
    pdu->out(pdu, s);
397
    s_mark_end(s);
398
    size = s->end - s->data;
399
    //g_hexdump_file("/tmp/taskq_DYNVC_CAPS_VERSION2.hexdump",s->data,size);
400
    MDBGLOG("drdynvc","INFO\t[%s()]: data out, sending (chan_id = %d)",__func__,g_drdynvc_chan_id);
401
    TC_MUTEX_LOCK(mutex_out);
402
    send_channel_data(g_drdynvc_chan_id, s->data, size);
403
    TC_MUTEX_UNLOCK(mutex_out);
404
405
    TC_THREAD_EXIT(NULL);
406
    return rv;
407
}
408
409
/*****************************************************************************/
410
int APP_CC
411
drdynvc_deinit(void) {
412
  ptrdiff_t idx = 0;
413
414
  MDBGLOG("drdynvc","INFO\t[%s()]: called",__func__);
415
416
  if (g_drdynvc_wait_obj > -1) {
417
    g_delete_wait_obj(g_drdynvc_wait_obj);
418
  }
419
420
  g_drdynvc_up			= 0;
421
  g_drdynvc_wait_obj		= -1;
422
  g_client_id			= 0x0001;
423
424
  if (g_ins != NULL) {
425
    //free_stream(g_ins);
426
    g_ins = (struct stream *)NULL;
427
  }
428
429
  TC_MUTEX_LOCK(mutex_drdynvc_arr);
430
  if (g_drdynvc_arr != NULL && g_drdynvc_count > 0) {
431
    for (idx = 0; idx < g_drdynvc_count; idx++) {
432
      if (g_drdynvc_arr[idx] != NULL) {
433
	if (g_drdynvc_arr[idx]->pid > 0) {
434
	  g_waitpid(g_drdynvc_arr[idx]->pid);
435
	}
436
	g_free(g_drdynvc_arr[idx]);
437
      }
438
    }
439
  }
440
  TC_MUTEX_UNLOCK(mutex_drdynvc_arr);
441
442
443
  return 0;
444
}
445
446
/*****************************************************************************/
447
int APP_CC drdynvc_data_in(struct stream * s, int chan_id, int chan_flags, int length, int total_length) {
448
  int rv = 0;
449
  ptrdiff_t idx = 0;
450
  struct stream * ls = (struct stream *)NULL;
451
  drdynvc_t * channel = (drdynvc_t *)NULL;
452
  struct trans * trans = (struct trans *)NULL;
453
454
  MDBGLOG("drdynvc","INFO\t[%s()]: called (chan_id = 0x%8.8x; chan_flags = 0x%8.8x; length = %d; total_length = %d) [%d, %d]", __func__, chan_id, chan_flags, length, total_length, g_getpid(), g_gettid());
455
456
  if (chan_flags == 0x00000000) {
457
  }
458
  else if ((chan_flags & 3) == chan_flags)
459
  {
460
    ls = s;
461
  }
462
  else
463
  {
464
    if (chan_flags & 1)
465
    {
466
      init_stream(g_ins, total_length)
467
    }
468
    in_uint8a(s, g_ins->end, length);
469
    g_ins->end += length;
470
    if ((chan_flags & 2) == 0)
471
    {
472
      MDBGLOG("drdynvc","INFO\t[%s()]: exiting",__func__);
473
      rv = 0;
474
      goto exit;
475
    }
476
    else {
477
      ls = g_ins;
478
    }
479
  }
480
481
  //g_hexdump_file("/tmp/taskq_drdynvc_data_in.hexdump",ls->data,(ls->end - ls->data));
482
483
  if (g_channel_list != NULL && g_channel_list->ChannelCount > 0)
484
  for (idx = (MAX_CHANNEL - 1); idx > -1; idx--) if (g_channel_list->ChannelList[idx] != NULL && g_channel_list->ChannelList[idx]->initialized == 1 && g_channel_list->ChannelList[idx]->ccon != NULL && g_channel_list->ChannelList[idx]->ccon->sck > -1) {
485
    if (g_channel_list->ChannelList[idx]->ccon != NULL) {
486
      channel = g_channel_list->ChannelList[idx];
487
      trans = channel->ccon;
488
      // MDBGLOG("drdynvc","DEBUG\t[%s()]: channel->channel_id=%d; channel->index=%d",__func__,channel->channel_id,channel->index);
489
      break;
490
    }
491
  }
492
493
  {
494
    uint8_t cmd = 0x00;
495
    union {
496
	BYTE		val;
497
	DYNVC_HEADER	hdr;
498
    } tmp;
499
    DYNVC_HEADER * hdr = &(tmp.hdr);
500
501
    g_memset(hdr,0,sizeof(DYNVC_HEADER));
502
    g_memcpy(hdr,ls->p,sizeof(DYNVC_HEADER));
503
504
    cmd = (hdr->Cmd & 0xf0) >> 4;
505
506
    switch (cmd) {
507
	case DRDYNVC_CAPABILITIES:
508
	  MDBGLOG("drdynvc","INFO\t[%s()]: hdr->Cmd = 0x%8.8x (DRDYNVC_CAPABILITIES)",__func__,hdr->Cmd);
509
	  rv = drdynvc_process_CAPABILITIES_RSP(ls);
510
	  break;
511
	case DRDYNVC_CREATE:
512
	  MDBGLOG("drdynvc","INFO\t[%s()]: hdr->Cmd = 0x%8.8x (DRDYNVC_CREATE)",__func__,hdr->Cmd);
513
	  rv = drdynvc_process_CREATE_RSP(ls, channel);
514
	  break;
515
	case DRDYNVC_DATAFIRST:
516
	  MDBGLOG("drdynvc","INFO\t[%s()]: hdr->Cmd = 0x%8.8x (DRDYNVC_DATAFIRST)",__func__,hdr->Cmd);
517
	  rv = drdynvc_process_DATA_FIRST(ls, channel);
518
	  break;
519
	case DRDYNVC_DATA:
520
	  MDBGLOG("drdynvc","INFO\t[%s()]: hdr->Cmd = 0x%8.8x (DRDYNVC_DATA)",__func__,hdr->Cmd);
521
	  rv = drdynvc_process_DATA(ls, channel);
522
	  break;
523
	case DRDYNVC_CLOSE:
524
	  MDBGLOG("drdynvc","INFO\t[%s()]: hdr->Cmd = 0x%8.8x (DRDYNVC_CLOSE)",__func__,hdr->Cmd);
525
	  rv = drdynvc_process_CLOSE(ls);
526
	  break;
527
	default:
528
	  MDBGLOG("drdynvc", "WARNING\t[%s()]: unknown opcode (cmd = 0x%8.8x; hdr->Cmd = 0x%8.8x)", __func__, cmd, hdr->Cmd);
529
	  break;
530
    }
531
  }
532
533
 exit:;
534
  return rv;
535
}
536
537
/*****************************************************************************/
538
int APP_CC
539
drdynvc_get_wait_objs(tbus * objs, int * count, int * timeout) {
540
  int rv = 0;
541
  ptrdiff_t lcount = 0;
542
  ptrdiff_t idx = 0;
543
  tbus sck = -1;
544
545
  if ((g_drdynvc_up == 0) || (objs == NULL) || (count == NULL) || g_is_child > 0)
546
  {
547
    MDBGLOG("drdynvc","ERROR\t[%s()]: exiting (g_drdynvc_up = %d, objs = %p, count = %d, g_is_child = %d)",__func__,g_drdynvc_up,objs,*count,g_is_child);
548
    rv = -1;
549
  }
550
  else if (g_drdynvc_wait_obj < 1) {
551
    MDBGLOG("drdynvc","WARNING\t[%s()]: g_drdynvc_wait_obj is not set",__func__);
552
    rv = -1;
553
  }
554
  else {
555
    lcount = *count;
556
    objs[lcount] = g_drdynvc_wait_obj;
557
    lcount++;
558
    TC_MUTEX_LOCK(mutex_channel_list);
559
    if (g_sck < 0) {
560
      TC_MUTEX_UNLOCK(mutex_channel_list);
561
      MDBGLOG("drdynvc","INFO\t[%s()]: g_sck not yet assigned...",__func__);
562
      g_sleep(500);
563
      TC_MUTEX_LOCK(mutex_channel_list);
564
    }
565
    if (g_sck > -1) {
566
      objs[lcount] = g_sck;
567
      lcount++;
568
    }
569
    else {
570
      MDBGLOG("drdynvc","WARNING\t[%s()]: g_sck still not yet assigned",__func__);
571
    }
572
    *count = lcount;
573
    if (g_channel_list != NULL && g_channel_list->ChannelCount > 0)
574
    for (idx = 0; idx < MAX_CHANNEL; idx++) if (g_channel_list->ChannelList[idx] != NULL && g_channel_list->ChannelList[idx]->initialized > 0 && g_channel_list->ChannelList[idx]->ccon != NULL && g_channel_list->ChannelList[idx]->ccon->sck > 0) {
575
	//drdynvc_t * channel = get_channel(idx);
576
	drdynvc_t * channel = g_channel_list->ChannelList[idx];
577
	if (channel != NULL && channel->initialized > 0 && channel->ccon != NULL && channel->ccon->sck > 0) {
578
	  //MDBGLOG("drdynvc","INFO\t[%s()]: adding socket %d",__func__,channel->ccon->sck);
579
	  //trans_get_wait_objs(channel->ccon, objs, count, NULL);
580
	  objs[lcount] = channel->ccon->sck;
581
	  lcount++;
582
	  *count = lcount;
583
	}
584
	else if (!(channel = get_channel(idx)) && channel != NULL && channel->initialized > 0 && channel->ccon != NULL && channel->ccon->sck > 0) {
585
	  objs[lcount] = channel->ccon->sck;
586
	  lcount++;
587
	  *count = lcount;
588
	}
589
	else {
590
	  MDBGLOG("drdynvc","ERROR\t[%s()]: unable to ascertain socket (channel = %p)",__func__,channel);
591
	}
592
	/*
593
	if (sck > 0) {
594
	  lcount = *count;
595
	  objs[lcount] = sck;
596
	  lcount++;
597
	  *count = lcount;
598
	}
599
	*/
600
    }
601
    TC_MUTEX_UNLOCK(mutex_channel_list);
602
  }
603
604
  return rv;
605
}
606
607
/*****************************************************************************/
608
int APP_CC
609
drdynvc_check_wait_objs(void) {
610
  int rv = 0;
611
  ptrdiff_t idx = 0;
612
613
  if (!g_drdynvc_up || g_is_child > 0) {
614
    rv = -1;
615
  }
616
  else {
617
    TC_MUTEX_LOCK(mutex_channel_list);
618
    if (g_is_wait_obj_set(g_drdynvc_wait_obj)) {
619
    }
620
    if (g_sck > -1 && g_is_wait_obj_set(g_sck)) {
621
      TC_MUTEX_UNLOCK(mutex_channel_list);
622
      drdynvc_handle_connection(g_sck);
623
      TC_MUTEX_LOCK(mutex_channel_list);
624
    }
625
    if (g_channel_list != NULL && g_channel_list->ChannelCount > 0 && g_channel_list->ChannelList != NULL) {
626
     for (idx = 0; idx < MAX_CHANNEL; idx++) if (g_channel_list->ChannelList != NULL && g_channel_list->ChannelList[idx] != NULL && g_channel_list->ChannelList[idx]->initialized > 0 && g_channel_list->ChannelList[idx]->ccon != NULL && g_channel_list->ChannelList[idx]->ccon->sck > -1) {
627
      drdynvc_t * channel = g_channel_list->ChannelList[idx];
628
      if (channel == NULL) {
629
	channel = get_channel(idx);
630
      }
631
      if (channel == NULL) {
632
	MDBGLOG("drdynvc","ERROR\t[%s()]: NULL pointer (idx = %d)",__func__,idx);
633
      }
634
      else {
635
	struct trans * ccon = (struct trans *)NULL;
636
	ccon = channel->ccon;
637
	/* handle any inbound replies from the child: */
638
	if (ccon == NULL) {
639
	  MDBGLOG("drdynvc","ERROR\t[%s()]: ccon is NULL",__func__);
640
	}
641
	else if (trans_check_wait_objs(ccon) != 0) {
642
	  rv = -1;
643
	}
644
      }
645
     }
646
    }
647
    TC_MUTEX_UNLOCK(mutex_channel_list);
648
  }
649
  return rv;
650
}
651
652
/*************************************************************************/
653
/*************************************************************************/
654
655
static int APP_CC
656
drdynvc_output_DYNVC_CREATE_REQ(struct stream * s, int ChannelId, const char * ChannelName) {
657
  int rv = 0;
658
  DYNVC_ANY pdu;
659
  DYNVC_CREATE_REQ * req = (DYNVC_CREATE_REQ *)(&(pdu.create_req));
660
661
  MDBGLOG("drdynvc","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
662
663
  g_memset(&req, 0, sizeof(DYNVC_CREATE_REQ));
664
665
  construct_DYNVC_CREATE_REQ(req);
666
  req->ChannelId = ChannelId;
667
  g_strncpy(req->ChannelName, ChannelName, 48);
668
  req->cbChId = DRDYNVC_BYTE;
669
  send_DYNVC_CREATE_REQ(req, s);
670
671
  MDBGLOG("drdynvc","INFO\t[%s()]: done.",__func__);
672
  return rv;
673
}
674
675
676
/*****************************************************************************/
677
static size_t APP_CC
678
app_data_in(struct trans * trans) {
679
  struct stream * s = (struct stream *)NULL;
680
  char odata[MAX_STREAM];
681
  struct stream os;
682
  char qdata[MAX_STREAM];
683
  struct stream qs;
684
  char tdata[MAX_STREAM];
685
  struct stream ts;
686
  struct stream * r = (struct stream *)NULL;
687
  struct stream * q = (struct stream *)NULL;
688
  struct stream * l = (struct stream *)NULL;
689
  callback_t * cb = (callback_t *)NULL;
690
  ptrdiff_t fpath_length = 0;
691
  ptrdiff_t size = 0;
692
  ptrdiff_t len = 0;
693
  ptrdiff_t idx = 0;
694
  int rdpchan_opcode = 0;
695
  int error = 0;
696
  ptrdiff_t opid = 0;
697
  int uniqid = 0;
698
  uint32_t tsize = 0x00000000;
699
  uint32_t calc_crc32 = 0x00000000;
700
  uint32_t crc32 = 0x00000000;
701
  uint32_t magic = 0x00000000;
702
  uint32_t channel_id = 0x00000000;
703
  void * pdu = (void *)NULL;
704
  BYTE * buf = (BYTE *)NULL;
705
  DYNVC_ANY item;
706
707
  MDBGLOG("drdynvc","INFO\t[%s()]: called",__func__);
708
709
  g_memset(&item,0,sizeof(DYNVC_ANY));
710
711
  if (trans == 0) {
712
    return 0;
713
  }
714
715
  g_memset((char *)tdata,0,sizeof(char)*MAX_STREAM);
716
  g_memset(&ts,0,sizeof(struct stream));
717
  ts.data = (char *)tdata;
718
  ts.p = ts.data;
719
  ts.end = ts.data;
720
  ts.size = MAX_STREAM;
721
  r = &ts;
722
  g_memset((char *)qdata,0,sizeof(char)*MAX_STREAM);
723
  g_memset(&qs,0,sizeof(struct stream));
724
  qs.data = (char *)qdata;
725
  qs.p = qs.data;
726
  qs.end = qs.data;
727
  qs.size = MAX_STREAM;
728
  q = &qs;
729
  g_memset((char *)odata,0,sizeof(char)*MAX_STREAM);
730
  g_memset(&os,0,sizeof(struct stream));
731
  os.data = (char *)odata;
732
  os.p = os.data;
733
  os.end = os.data;
734
  os.size = MAX_STREAM;
735
  l = &os;
736
737
  s = (struct stream *)trans_get_in_s(trans);
738
  g_memcpy(l->data,s->data,s->size);
739
  l->size = s->size;
740
  if ((s->p - s->data) > 0) {
741
    l->p += (s->p - s->data);
742
  }
743
  if ((s->end - s->data) > 0) {
744
    l->end = l->data + (s->end - s->data);
745
  }
746
  g_memcpy(q->data,s->data,s->size);
747
  q->size = s->size;
748
  if ((s->p - s->data) > 0) {
749
    q->p += (s->p - s->data);
750
  }
751
  if ((s->end - s->data) > 0) {
752
    q->end = q->data + (s->end - s->data);
753
  }
754
  in_uint32_le(q, magic);
755
  in_uint32_le(q, rdpchan_opcode);
756
  in_uint32_le(q, size);
757
  in_uint32_le(q, channel_id);
758
  in_uint32_le(q, uniqid);
759
  in_uint32_le(q, crc32);
760
761
  MDBGLOG("drdynvc","DEBUG\t[%s()]: size = %d; magic = 0x%8.8x (should be 0x%8.8x); rdpchan_opcode = 0x%8.8x",__func__,size,magic,RDP_PACKET_MAGIC,rdpchan_opcode);
762
763
  if (size > 0) {
764
    char * p = (char *)NULL;
765
    size_t tlen = size;
766
    trans_force_read(trans, tlen);
767
    s->p += 24;
768
    if ((rdpchan_opcode == RDPCHAN_DATAFIRST) || ((rdpchan_opcode & RDPCHAN_DATAFIRST) == rdpchan_opcode && rdpchan_opcode != 0x0000)) {
769
      in_uint32_le(s, tsize);
770
      tlen -= 4;
771
    }
772
    p = s->p;
773
    if (tlen > 0) {
774
      buf = (BYTE *)g_malloc(sizeof(BYTE) * tlen, 1);
775
      in_uint8a(s, (char *)buf, tlen);
776
    }
777
    calc_crc32 = Crc32_ComputeBuf(0, p, tlen);
778
    MDBGLOG("drdynvc", "INFO\t[%s()]: crc32 = 0x%8.8x, calc_crc32 = 0x%8.8x", __func__, crc32, calc_crc32);
779
    len = tlen;
780
  }
781
  
782
  MDBGLOG("drdynvc","INFO\t[%s()]: ** rdpchan_opcode = 0x%8.8x; size = %d; uniqid = %d; buf = \"%s\"; tsize = %d",__func__,rdpchan_opcode,size,uniqid,(char *)buf,tsize);
783
784
  make_stream(r);
785
  init_stream(r, MAX_STREAM);
786
787
  if (error == 0) {
788
    unsigned char found = 0;
789
    TC_MUTEX_LOCK(mutex_cb);
790
    for (opid = 4; opid < MAX_PENDING; opid++) {
791
      if (g_callbacks[opid].opid < 1) {
792
	found = 1;
793
	break;
794
      }
795
    }
796
    if (found > 0) {
797
      g_memset((callback_t *)(&(g_callbacks[opid])), 0, sizeof(callback));
798
      g_callbacks[opid].opid = opid;
799
      g_callbacks[opid].type = 1;
800
      g_callbacks[opid].channel = trans->callback_data;
801
      g_callbacks[opid].opcode = rdpchan_opcode;
802
      g_callbacks[opid].CompletionId = opid;
803
      g_callbacks[opid].trans = trans;
804
      g_callbacks[opid].uniqid = uniqid;
805
      cb = &(g_callbacks[opid]);
806
    }
807
    if (found < 1) {
808
      MDBGLOG("drdynvc","ERROR\t[%s()]: unable to allocate callback slot (opcode = %8.8x; opid = %d)",__func__,rdpchan_opcode,opid);
809
      error = -1;
810
    }
811
    else if (cb == NULL) {
812
      MDBGLOG("drdynvc","ERROR\t[%s()]: failed to assign callback to operation (opcode = %8.8x; opid = %d)",__func__,rdpchan_opcode,opid);
813
      error = -1;
814
    }
815
    else {
816
      switch(rdpchan_opcode) {
817
	case RDPCHAN_OPEN:
818
	  MDBGLOG("drdynvc","INFO\t[%s()]: opcode = RDPCHAN_OPEN",__func__);
819
	  {
820
	    DYNVC_CREATE_REQ * pdu = &(item.create_req);
821
	    construct_DYNVC_CREATE_REQ(pdu);
822
	    pdu->ChannelId = cb->channel->channel_id;
823
	    g_strncpy(pdu->ChannelName, buf, 48);
824
	    pdu->cbChId = DRDYNVC_BYTE;
825
	    if (pdu->out == NULL) {
826
	      MDBGLOG("drdynvc","ERROR\t[%s()]: pdu->out() is NULL",__func__);
827
	    }
828
	    else {
829
	      pdu->out(pdu, r);
830
	    }
831
	  }
832
	  break;
833
	case RDPCHAN_CLOSE:
834
	  MDBGLOG("drdynvc","INFO\t[%s()]: opcode = RDPCHAN_CLOSE",__func__);
835
	  {
836
	    DYNVC_CLOSE * pdu = &(item.close);
837
	    construct_DYNVC_CLOSE(pdu);
838
	    pdu->ChannelId = cb->channel->channel_id;
839
	    if (pdu->out == NULL) {
840
	      MDBGLOG("drdynvc","ERROR\t[%s()]: pdu->out() is NULL",__func__);
841
	    }
842
	    else {
843
	      pdu->out(pdu, r);
844
	    }
845
	  }
846
	  break;
847
	case RDPCHAN_DATAFIRST:
848
	  MDBGLOG("drdynvc","INFO\t[%s()]: opcode = RDPCHAN_DATAFIRST",__func__);
849
	  {
850
	    DYNVC_DATA_FIRST * pdu = &(item.datafirst);
851
	    construct_DYNVC_DATA_FIRST(pdu);
852
	    pdu->ChannelId = cb->channel->channel_id;
853
	    if (pdu->out == NULL) {
854
	      MDBGLOG("drdynvc","ERROR\t[%s()]: pdu->out() is NULL",__func__);
855
	    }
856
	    else {
857
	      if (len > 0) {
858
		pdu->Length = len;
859
		g_memcpy(pdu->Data, buf, len);
860
	      }
861
	      pdu->out(pdu, r);
862
	    }
863
	  }
864
	  break;
865
	case RDPCHAN_DATA:
866
	  MDBGLOG("drdynvc","INFO\t[%s()]: opcode = RDPCHAN_DATA",__func__);
867
	  {
868
	    //DYNVC_DATA * pdu = &(item.data);
869
	    DYNVC_DATA * pdu = (DYNVC_DATA *)NULL;
870
	    pdu = (DYNVC_DATA *)g_malloc(sizeof(DYNVC_DATA) + len, 1);
871
	    construct_DYNVC_DATA(pdu);
872
	    pdu->Sp = 0x01;
873
	    pdu->ChannelId = cb->channel->channel_id;
874
	    if (pdu->out == NULL) {
875
	      MDBGLOG("drdynvc","ERROR\t[%s()]: pdu->out() is NULL",__func__);
876
	    }
877
	    else {
878
	      if (len > 0) {
879
		pdu->Length = len;
880
		g_memcpy(pdu->Data, buf, len);
881
	      }
882
	      pdu->out(pdu, r);
883
	    }
884
	  }
885
	  break;
886
	case RDPCHAN_QUERY:
887
	  MDBGLOG("drdynvc","INFO\t[%s()]: opcode = RDPCHAN_QUERY",__func__);
888
	  {
889
	  }
890
	  break;
891
	default:
892
	  MDBGLOG("drdynvc","ERROR\t[%s()]: unrecognized opcode (0x%8.8x)",__func__,rdpchan_opcode);
893
	  free_stream(r);
894
	  r = (struct stream *)NULL;
895
	  r = trans_get_out_s(trans, MAX_STREAM);
896
	  magic = RDP_PACKET_MAGIC;
897
	  crc32 = 0x00000000;
898
	  size = 0x00000000;
899
	  out_uint32_le(r, magic);
900
	  out_uint32_le(r, RDPCHAN_ERROR);
901
	  out_uint32_le(r, size);
902
	  out_uint32_le(r, channel_id);
903
	  out_uint32_le(r, uniqid);
904
	  out_uint32_le(r, crc32);
905
	  s_mark_end(r);
906
	  trans_force_write(trans);
907
	  r->end = r->data;
908
  	  break;
909
      }
910
      /* send the assembled PDU to the RDP client: */
911
      s_mark_end(r);
912
      size = r->end - r->data;
913
      if (size > 0) {
914
	TC_MUTEX_LOCK(mutex_out);
915
	error = send_channel_data(g_drdynvc_chan_id, r->data, size);
916
	TC_MUTEX_UNLOCK(mutex_out);
917
	//g_hexdump_file("/tmp/taskq_hex_rdata.hexdump",r->data,size);
918
	MDBGLOG("drdynvc","INFO\t[%s()]: sent channel data (size = %d)",__func__,size);
919
	g_memset(r->data,0,MAX_STREAM);
920
	free_stream(r);
921
      }
922
      else {
923
	MDBGLOG("drdynvc","ERROR\t[%s()]: output PDU is empty (size == 0)",__func__);
924
      }
925
    }
926
    TC_MUTEX_UNLOCK(mutex_cb);
927
  }
928
  return error;
929
}
930
931
932
/*****************************************************************************/
933
static ptrdiff_t APP_CC get_channel_index(ptrdiff_t ChannelId) {
934
  ptrdiff_t rv = -1;
935
  ptrdiff_t idx = 0;
936
937
  if (TC_MUTEX_TRYLOCK(mutex_channel_list) == 0) {
938
    if (ChannelId < 0 || g_channel_list == NULL || g_channel_list->ChannelList == NULL || g_channel_list->ChannelCount < 1) {
939
      rv = -1;
940
    }
941
    else for (idx = 0; idx < g_channel_list->ChannelCount; idx ++) {
942
      if (g_channel_list->ChannelList[idx] != NULL && g_channel_list->ChannelList[idx]->channel_id == ChannelId) {
943
        rv = idx;
944
        break;
945
      }
946
    }
947
    TC_MUTEX_UNLOCK(mutex_channel_list);
948
  }
949
  else {
950
    if (ChannelId < 0 || g_channel_list == NULL || g_channel_list->ChannelList == NULL || g_channel_list->ChannelCount < 1) {
951
      rv = -1;
952
    }
953
    else for (idx = 0; idx < g_channel_list->ChannelCount; idx ++) {
954
      if (g_channel_list->ChannelList[idx] != NULL && g_channel_list->ChannelList[idx]->channel_id == ChannelId) {
955
        rv = idx;
956
        break;
957
      }
958
    }
959
  }
960
961
  return rv;
962
}
963
964
/*****************************************************************************/
965
static int APP_CC drdynvc_process_CAPABILITIES_RSP(struct stream * s) {
966
    int rv = 0;
967
    char * tp = (char *)(s->p);
968
    DYNVC_CAPS_RSP * creply = (DYNVC_CAPS_RSP *)NULL;
969
    creply = RDPEDYC_NEW(DYNVC_CAPS_RSP);
970
    get_DYNVC_CAPS_RSP(creply, s);
971
    //g_hexdump_file("/tmp/taskq_hex_DYNVC_CAPS_RSP.hexdump",tp,(s->end - tp));
972
    g_client_announce_reply_received = 1;
973
    return rv;
974
}
975
976
/*****************************************************************************/
977
static int APP_CC drdynvc_process_CREATE_RSP(struct stream * s, rdpchan_t * chan) {
978
    int rv = 0;
979
    uint32_t * ures = (uint32_t *)NULL;
980
    int32_t * res = (int32_t *)NULL;
981
    char * tp = (char *)(s->p);
982
    DYNVC_CREATE_RSP * creply = (DYNVC_CREATE_RSP *)NULL;
983
    struct trans * trans = (struct trans *)NULL;
984
    trans = chan->ccon;
985
    creply = RDPEDYC_NEW(DYNVC_CREATE_RSP);
986
    get_DYNVC_CREATE_RSP(creply, s);
987
    res = (int32_t *)(&(creply->CreationStatus));
988
    ures = (uint32_t *)(&(creply->CreationStatus));
989
    MDBGLOG("drdynvc","INFO\t[%s()]: CreationStatus = 0x%8.8x (\"%s\", ChannelId = %d)",__func__,(*ures),(((*res) < 0)?nterr_msg((*ures)):"OK"),creply->ChannelId);
990
    //g_hexdump_file("/tmp/taskq_hex_DYNVC_CREATE_RSP.hexdump",tp,(s->end - tp));
991
    chan->dynamic_channel_index = creply->ChannelId;
992
    if (trans == NULL) {
993
	MDBGLOG("drdynvc","ERROR\t[%s()]: trans is NULL",__func__);
994
    }
995
    else if (g_channel_list != NULL && g_channel_list->ChannelList != NULL && g_channel_list->ChannelCount > 0) {
996
	struct stream * r = (struct stream *)NULL;
997
	r = trans_get_out_s(trans, MAX_STREAM);
998
	//out_uint32_t(r, *ures);
999
	if (*ures == 0x00000000) {
1000
	  const char rmsg[] = "OK\n";
1001
	  char dmsg[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1002
	  g_snprintf(dmsg, (sizeof(dmsg) - 1), "%d", creply->ChannelId);
1003
	  out_uint8a(r, rmsg, 3);
1004
	  out_uint8a(r, dmsg, g_strlen(dmsg));
1005
	  out_uint8(r, '\n');
1006
	}
1007
	else {
1008
	  const char rmsg[] = "ERROR\n";
1009
	  out_uint8a(r, rmsg, 6);
1010
	}
1011
	s_mark_end(r);
1012
	r->p = r->data;
1013
	trans_force_write(trans);
1014
	//r->p = r->end = r->data;
1015
    }
1016
  end:;
1017
    MDBGLOG("drdynvc","INFO\t[%s()]: done.",__func__);
1018
    return rv;
1019
}
1020
1021
/*****************************************************************************/
1022
static int APP_CC OLD_drdynvc_process_DATA_FIRST(struct stream * s, rdpchan_t * ichan) {
1023
    int rv = 0;
1024
    ptrdiff_t idx = -1;
1025
    char * tp = (char *)NULL;
1026
    char * cp = (char *)NULL;
1027
    DYNVC_DATA_FIRST * dp = (DYNVC_DATA_FIRST *)NULL;
1028
    DYNVC_DATA_FIRST * cdata = (DYNVC_DATA_FIRST *)NULL;
1029
    if (s == NULL || ichan == NULL || s->p == NULL) {
1030
      rv = -1;
1031
      goto end;
1032
    }
1033
    dp = (DYNVC_DATA_FIRST *)(s->p);
1034
    cdata = RDPEDYC_NEW(DYNVC_DATA_FIRST);
1035
    tp = s->p;
1036
    cp = (char *)(dp->Data);
1037
    get_DYNVC_DATA_FIRST(cdata, s);
1038
    idx = cdata->ChannelId;
1039
    if (idx > -1 && idx < MAX_CHANNEL && idx < g_drdynvc_count) {
1040
      drdynvc_t * chan = (drdynvc_t *)NULL;
1041
      struct stream * qs = (struct stream *)NULL;
1042
      DECLARE_SQ(tmp);
1043
      chan = get_channel(idx);
1044
      cp = cdata->Data;
1045
      TC_MUTEX_LOCK(mutex_data);
1046
      g_data_in_progress[idx] = 1;
1047
      TC_MUTEX_LOCK(&(chan->ilock));
1048
      chan->istatus = 1;
1049
      chan->ilen = cdata->Length;
1050
      chan->irem = chan->ilen;
1051
      if (chan->ilen == 0 || cp == NULL) {
1052
	chan->ilen = 0;
1053
	chan->irem = 0;
1054
	chan->ihead = (stream_list_t *)NULL;
1055
	chan->istatus = 0;
1056
      }
1057
      else if (s->p > cp && tmp != NULL) {
1058
	size_t tlen = (s->p > cp) ? (s->p - cp) : 0;
1059
	make_stream(qs);
1060
	init_stream(qs,tlen);
1061
	g_memcpy(qs->data,cp,tlen);
1062
	tmp->s = qs;
1063
	SQ_ENQ(chan->ihead, tmp);
1064
	chan->irem -= tlen;
1065
	TC_COND_SIGNAL(cond_data);
1066
	{
1067
	  tc_t tattr;
1068
	  tc_p pattr = &tattr;
1069
	  g_memset(pattr,0,sizeof(tc_t));
1070
	  TC_CONDATTR_INIT(pattr);
1071
	  TC_CONDATTR_SETPSHARED(pattr, TC_PROCESS_PRIVATE);
1072
	  TC_COND_CREATE(cond_data, pattr);
1073
	}
1074
      }
1075
      TC_MUTEX_UNLOCK(&(chan->ilock));
1076
      TC_MUTEX_UNLOCK(mutex_data);
1077
    }
1078
  end:;
1079
    return rv;
1080
}
1081
1082
/*****************************************************************************/
1083
static int APP_CC drdynvc_process_DATA_FIRST(struct stream * s, rdpchan_t * ichan) {
1084
    int rv = 0;
1085
    if (s == NULL || s->data == NULL || s->p == NULL || s->end == NULL || s->end <= s->p) {
1086
      MDBGLOG("drdynvc","ERROR\t[%s()]: stream \"s\" is NULL",__func__);
1087
      rv = -1;
1088
    }
1089
    else {
1090
      int pres = 0;
1091
      uint8_t z = 0;
1092
      ptrdiff_t idx = -1;
1093
      unsigned char in_progress = 0;
1094
      char * tp = (char *)NULL;
1095
      char * cp = (char *)NULL;
1096
      DYNVC_DATA_FIRST * dp = (DYNVC_DATA_FIRST *)NULL;
1097
      DYNVC_DATA_FIRST * cdata = (DYNVC_DATA_FIRST *)NULL;
1098
      struct trans * trans = (struct trans *)NULL;
1099
      s->p = s->data;
1100
      s->p += 4;
1101
      cdata = (DYNVC_DATA_FIRST *)g_malloc((sizeof(DYNVC_DATA_FIRST) + (s->end - s->p)), 1);
1102
      construct_DYNVC_DATA_FIRST(cdata);
1103
      in_uint32_le(s, cdata->Length);
1104
      tp = s->p;
1105
      MDBGLOG("drdynvc","INFO\t[%s()]: cdata->Length = %d",__func__,cdata->Length);
1106
      if (ichan == NULL) {
1107
	MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: invalid channel",__func__,__LINE__);
1108
	rv = -1;
1109
	goto exit;
1110
      }
1111
      else {
1112
	ptrdiff_t tlen = 0;
1113
	struct stream * r = (struct stream *)NULL;
1114
	drdynvc_t * chan = (drdynvc_t *)NULL;
1115
	chan = ichan;
1116
	if (chan == NULL) {
1117
	  MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: chan is NULL",__func__,__LINE__);
1118
	  rv = -1;
1119
	  goto exit;
1120
	}
1121
	idx = cdata->ChannelId;
1122
	cp = cdata->Data;
1123
	tlen = cdata->Length;
1124
	if (tlen < 1) {
1125
	  MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: tlen is empty",__func__,__LINE__);
1126
	  rv = -1;
1127
	  goto exit;
1128
	}
1129
	else if (tlen > MAX_STREAM) {
1130
	  MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: too much data (tlen = %d)",__func__,__LINE__,tlen);
1131
	  rv = -1;
1132
	  goto exit;
1133
	}
1134
	trans = chan->ccon;
1135
	TC_MUTEX_LOCK(mutex_data);
1136
	g_data_in_progress[idx] = 1;
1137
	{
1138
	  struct stream * qs = (struct stream *)NULL;
1139
	  DECLARE_SQ(tmp);
1140
	  make_stream(qs);
1141
	  init_stream(qs,tlen);
1142
	  g_memcpy(qs->data,cp,tlen);
1143
	  tmp->s = qs;
1144
	  TC_MUTEX_LOCK(&(chan->ilock));
1145
	  chan->istatus = 1;
1146
	  chan->ilen = cdata->Length;
1147
	  chan->irem = chan->ilen - tlen;
1148
	  SQ_ENQ(chan->ihead, tmp);
1149
	  TC_COND_SIGNAL(cond_data);
1150
	  {
1151
	    tc_t tattr;
1152
	    tc_p pattr = &tattr;
1153
	    g_memset(pattr,0,sizeof(tc_t));
1154
	    TC_CONDATTR_INIT(pattr);
1155
	    TC_CONDATTR_SETPSHARED(pattr, TC_PROCESS_PRIVATE);
1156
	    TC_COND_CREATE(cond_data, pattr);
1157
	  }
1158
	  TC_MUTEX_UNLOCK(&(chan->ilock));
1159
	  TC_MUTEX_UNLOCK(mutex_data);
1160
	}
1161
      }
1162
    }
1163
 exit:;
1164
    return rv;
1165
}
1166
1167
/*****************************************************************************/
1168
static int APP_CC drdynvc_process_DATA(struct stream * s, rdpchan_t * ichan) {
1169
    int rv = 0;
1170
    if (s == NULL || s->data == NULL || s->p == NULL || s->end == NULL || s->end <= s->p) {
1171
      MDBGLOG("drdynvc","ERROR\t[%s()]: stream \"s\" is NULL",__func__);
1172
      rv = -1;
1173
    }
1174
    else {
1175
      ptrdiff_t idx = -1;
1176
      unsigned char in_progress = 0;
1177
      char * tp = (char *)NULL;
1178
      char * cp = (char *)NULL;
1179
      DYNVC_DATA * dp = (DYNVC_DATA *)(s->p);
1180
      DYNVC_DATA * cdata = (DYNVC_DATA *)NULL;
1181
      struct trans * trans = (struct trans *)NULL;
1182
      cdata = (DYNVC_DATA *)g_malloc((sizeof(DYNVC_DATA) + (s->end - s->p)), 1);
1183
      tp = s->p;
1184
      cp = (char *)(dp->Data);
1185
      cdata->Length = (DWORD)(s->end - s->p);
1186
      if (cdata->Length > 0) {
1187
	g_memcpy(cdata->Data, s->p, cdata->Length);
1188
      }
1189
      if (ichan == NULL) {
1190
	MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: invalid channel",__func__,__LINE__);
1191
	rv = -1;
1192
	goto exit;
1193
      }
1194
      else {
1195
	ptrdiff_t tlen = 0;
1196
	struct stream * r = (struct stream *)NULL;
1197
	drdynvc_t * chan = (drdynvc_t *)NULL;
1198
	chan = ichan;
1199
	if (chan == NULL) {
1200
	  MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: chan is NULL",__func__,__LINE__);
1201
	  rv = -1;
1202
	  goto exit;
1203
	}
1204
	cp = cdata->Data;
1205
	tlen = cdata->Length;
1206
	if (tlen < 1) {
1207
	  MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: tlen is empty",__func__,__LINE__);
1208
	  rv = -1;
1209
	  goto exit;
1210
	}
1211
	else if (tlen > MAX_STREAM) {
1212
	  MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: too much data (tlen = %d)",__func__,__LINE__,tlen);
1213
	  rv = -1;
1214
	  goto exit;
1215
	}
1216
	trans = chan->ccon;
1217
	idx = cdata->ChannelId;
1218
	TC_MUTEX_LOCK(mutex_data);
1219
	in_progress = g_data_in_progress[idx];
1220
	if (1 || !in_progress) {
1221
	  unsigned char tlocked = 0;
1222
	  if (trans != NULL && trans->lock != NULL) {
1223
	    TC_MUTEX_LOCK(trans->lock);
1224
	    trans->locked = 1;
1225
	    tlocked = 1;
1226
	  }
1227
	  r = trans_get_out_s(trans, tlen);
1228
	  if (r == NULL || r->data == NULL || r->size < tlen) {
1229
	    if (tlocked) {
1230
	      trans->locked = 0;
1231
	      TC_MUTEX_UNLOCK(trans->lock);
1232
	      tlocked = 0;
1233
	    }
1234
	    MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: r is NULL or invalid",__func__,__LINE__);
1235
	    rv = -1;
1236
	    goto exit;
1237
	  }
1238
	  else {
1239
	    out_uint8a(r, cp, tlen);
1240
	    s_mark_end(r);
1241
	    MDBGLOG("drdynvc","INFO\t[%s() @ %d]: about to call trans_force_write() [trans->sck = %d; tlen = %d; r->end - r->data = %d]:",__func__,__LINE__,trans->sck,tlen,(r->end - r->data));
1242
	    trans_force_write(trans);
1243
	    MDBGLOG("drdynvc","INFO\t[%s() @ %d]: trans_force_write() finished",__func__,__LINE__);
1244
	  }
1245
	  if (tlocked) {
1246
	    trans->locked = 0;
1247
	    TC_MUTEX_UNLOCK(trans->lock);
1248
	    tlocked = 0;
1249
	  }
1250
	  TC_MUTEX_UNLOCK(mutex_data);
1251
	}
1252
	else {
1253
	  struct stream * qs = (struct stream *)NULL;
1254
	  DECLARE_SQ(tmp);
1255
	  make_stream(qs);
1256
	  init_stream(qs,tlen);
1257
	  g_memcpy(qs->data,cp,tlen);
1258
	  tmp->s = qs;
1259
	  TC_MUTEX_LOCK(&(chan->ilock));
1260
	  SQ_ENQ(chan->ihead, tmp);
1261
	  TC_COND_SIGNAL(cond_data);
1262
	  {
1263
	    tc_t tattr;
1264
	    tc_p pattr = &tattr;
1265
	    g_memset(pattr,0,sizeof(tc_t));
1266
	    TC_CONDATTR_INIT(pattr);
1267
	    TC_CONDATTR_SETPSHARED(pattr, TC_PROCESS_PRIVATE);
1268
	    TC_COND_CREATE(cond_data, pattr);
1269
	  }
1270
	  if (chan->irem > 0) {
1271
	    if (chan->irem > tlen) {
1272
	      MDBGLOG("drdynvc","ERROR\t[%s()]: incoming data is greater than the remaining count",__func__);
1273
	      chan->irem = 0;
1274
	    }
1275
	    else {
1276
	      chan->irem -= tlen;
1277
	    }
1278
	  }
1279
	  if (chan->irem == 0) {
1280
	    tc_t tattr;
1281
	    tc_p pattr = &tattr;
1282
	    g_memset(pattr,0,sizeof(tc_t));
1283
	    TC_CONDATTR_INIT(pattr);
1284
	    g_data_in_progress[idx] = 0;
1285
	    chan->ilen = 0;
1286
	    chan->istatus = 0;
1287
	    r = trans_get_out_s(trans, MAX_STREAM);
1288
	    if (r == NULL || r->data == NULL) {
1289
	      MDBGLOG("drdynvc","ERROR\t[%s() @ %d]: r is NULL or invalid",__func__,__LINE__);
1290
	      rv = -1;
1291
	      goto exit;
1292
	    }
1293
	    TC_COND_BROADCAST(&(chan->icv));
1294
	    TC_COND_CREATE(&(chan->icv), pattr);
1295
	  }
1296
	  TC_MUTEX_UNLOCK(&(chan->ilock));
1297
	  TC_MUTEX_UNLOCK(mutex_data);
1298
	}
1299
      }
1300
    }
1301
 exit:;
1302
    return rv;
1303
}
1304
1305
/*****************************************************************************/
1306
static int APP_CC drdynvc_process_CLOSE(struct stream * s) {
1307
    int rv = 0;
1308
    ptrdiff_t idx = -1;
1309
    drdynvc_t * chan = (drdynvc_t *)NULL;
1310
    char * tp = (char *)(s->p);
1311
    DYNVC_CLOSE * cclose = (DYNVC_CLOSE *)NULL;
1312
    cclose = RDPEDYC_NEW(DYNVC_CLOSE);
1313
    get_DYNVC_CLOSE(cclose, s);
1314
    //g_hexdump_file("/tmp/taskq_hex_DYNVC_CLOSE.hexdump",tp,(s->end - tp));
1315
    idx = cclose->ChannelId;
1316
    if (idx > -1 && idx < MAX_CHANNEL && idx < g_drdynvc_count && (chan = get_channel(idx)) != NULL) {
1317
      ptrdiff_t j = 0;
1318
      TC_MUTEX_LOCK(mutex_data);
1319
      if (g_drdynvc_arr[idx] != NULL && g_drdynvc_arr[idx]->channel_id == idx) {
1320
	  drdynvc_t * tmp = g_drdynvc_arr[idx];
1321
	  TC_MUTEX_LOCK(&(tmp->ilock));
1322
	  g_drdynvc_arr[idx] = (drdynvc_t *)NULL;
1323
	  TC_MUTEX_UNLOCK(&(tmp->ilock));
1324
	  g_free(tmp);
1325
	  tmp = (drdynvc_t *)NULL;
1326
      }
1327
      else for (j = 0; j < g_drdynvc_count; j++) {
1328
	if (g_drdynvc_arr[j] != NULL && g_drdynvc_arr[j]->channel_id == idx) {
1329
	  drdynvc_t * tmp = g_drdynvc_arr[j];
1330
	  TC_MUTEX_LOCK(&(tmp->ilock));
1331
	  g_drdynvc_arr[j] = (drdynvc_t *)NULL;
1332
	  TC_MUTEX_UNLOCK(&(tmp->ilock));
1333
	  g_free(tmp);
1334
	  tmp = (drdynvc_t *)NULL;
1335
	  break;
1336
	}
1337
      }
1338
      TC_MUTEX_UNLOCK(mutex_data);
1339
    }
1340
    return rv;
1341
}
1342
1343
/*****************************************************************************/
1344
static inline drdynvc_t * APP_CC get_channel(DWORD arg) {
1345
    drdynvc_t * rv = (drdynvc_t *)NULL;
1346
    ptrdiff_t i = 0;
1347
    if (arg > -1 && arg < MAX_CHANNEL && arg < g_drdynvc_count && g_drdynvc_arr[arg] != NULL && g_drdynvc_arr[arg]->channel_id == arg) {
1348
      rv = g_drdynvc_arr[arg];
1349
    }
1350
    else if (g_drdynvc_arr != NULL && g_drdynvc_count > 0) {
1351
      for (i = 0; i < g_drdynvc_count; i++) {
1352
	drdynvc_t * tmp = g_drdynvc_arr[i];
1353
	if (tmp != NULL && tmp->channel_id == arg) {
1354
	  rv = tmp;
1355
	  break;
1356
	}
1357
      }
1358
    }
1359
    return rv;
1360
}
1361
1362
/*****************************************************************************/
1363
static void * APP_CC drdynvc_data_loop(void * arg) {
1364
    void * rv = (void *)NULL;
1365
    unsigned char done = 0;
1366
    TC_MUTEX_LOCK(mutex_close);
1367
    done = g_done;
1368
    TC_MUTEX_UNLOCK(mutex_close);
1369
    while (!done) {
1370
      ptrdiff_t i = 0;
1371
      TC_MUTEX_LOCK(mutex_data);
1372
      TC_COND_WAIT(cond_data, mutex_data);
1373
      for (i = 0; i < MAX_CHANNEL && i < g_drdynvc_count; i++) if (g_drdynvc_arr[i] != NULL && g_drdynvc_arr[i]->ihead != NULL) {
1374
	drdynvc_t * chan = g_drdynvc_arr[i];
1375
	stream_list_t * item = (stream_list_t *)NULL;
1376
	do {
1377
	  struct stream * s = (struct stream *)NULL;
1378
	  TC_MUTEX_LOCK(&(chan->ilock));
1379
	  SQ_DEQ(chan->ihead, &item);
1380
	  TC_MUTEX_UNLOCK(&(chan->ilock));
1381
	  if (item != NULL) {
1382
	    s = item->s;
1383
	    if (s == NULL) {
1384
	      MDBGLOG("drdynvc","WARNING\t[%s()]: item->s is NULL",__func__);
1385
	    }
1386
	    else {
1387
	      MDBGLOG("drdynvc","INFO\t[%s()]: outputting buffer (item = %p; size = %d; (end - data) = %d)",__func__,s,s->size,(s->end - s->data));
1388
	      //g_hexdump_file("/tmp/taskq_hex_buffer.hexdump",s->data,(s->end - s->data));
1389
	    }
1390
	  }
1391
	} while (item != NULL);
1392
      }
1393
      TC_MUTEX_UNLOCK(mutex_data);
1394
      TC_MUTEX_LOCK(mutex_close);
1395
      done = g_done;
1396
      TC_MUTEX_UNLOCK(mutex_close);
1397
    }
1398
    TC_THREAD_EXIT(NULL);
1399
    return rv;
1400
}
1401
1402
/*****************************************************************************/
1403
static int APP_CC drdynvc_handle_connection(tbus sck_obj) {
1404
  int rv = 0;
1405
  tbus in_sck = -1;
1406
  int error = 0;
1407
  drdynvc_t * channel = (drdynvc_t *)NULL;
1408
  tc_t tattr;
1409
  tc_t wattr;
1410
  tc_p pattr = &tattr;
1411
  tc_p rattr = &wattr;
1412
  MDBGLOG("drdynvc","INFO\t[%s()]: incoming connection",__func__);
1413
  if (sck_obj < 1) {
1414
    sck_obj = g_sck;
1415
  }
1416
  in_sck = g_tcp_accept(sck_obj);
1417
  if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck)) {
1418
    /* should not get here */
1419
    g_sleep(100);
1420
  }
1421
  else if (in_sck == -1) {
1422
    /* error, should not get here */
1423
  }
1424
  else {
1425
    /* we've got a connection */
1426
    MDBGLOG("drdynvc", "INFO\t[%s()]: new connection (sck_obj = %d, in_sck = %d)",__func__,sck_obj,in_sck);
1427
    g_memset(pattr,0,sizeof(tc_t));
1428
    g_memset(rattr,0,sizeof(tc_t));
1429
    TC_MUTEX_LOCK(mutex_channel_list);
1430
    if (g_sck_arr == NULL) {
1431
      g_sck_arr = (tbus *)g_malloc(sizeof(tbus), 1);
1432
      g_sck_arr[0] = -1;
1433
    }
1434
    else {
1435
      g_sck_arr = (tbus *)g_realloc(g_sck_arr, sizeof(tbus) * (g_sck_count + 1));
1436
      g_sck_arr[g_sck_count] = -1;
1437
    }
1438
    g_sck_arr[g_sck_count] = in_sck;
1439
    g_sck_count++;
1440
    if (g_channel_list == NULL) {
1441
      g_channel_list = (drdynvc_list_t *)g_malloc(sizeof(drdynvc_list_t), 1);
1442
    }
1443
    if (g_channel_list->ChannelList == NULL) {
1444
      unsigned int i = 0;
1445
      g_channel_list->ChannelList = (drdynvc_t **)g_malloc(sizeof(size_t) * MAX_CHANNEL, 1);
1446
    }
1447
    else {
1448
      //g_channel_list->ChannelList = (drdynvc_t **)g_realloc(g_channel_list->ChannelList, sizeof(size_t) * (g_channel_list->ChannelCount + 1));
1449
      g_channel_list->ChannelList = (drdynvc_t **)realloc(g_channel_list->ChannelList, sizeof(size_t) * (g_channel_list->ChannelCount + 1));
1450
    }
1451
    channel = (drdynvc_t *)g_malloc(sizeof(drdynvc_t) + 48, 1);
1452
    TC_MUTATTR_INIT(rattr);
1453
    TC_MUTATTR_SETTYPE(rattr,TC_MUTEX_ERRORCHECK);
1454
    TC_MUTATTR_SETPSHARED(rattr,TC_PROCESS_PRIVATE);
1455
    TC_CONDATTR_INIT(pattr);
1456
    TC_CONDATTR_SETPSHARED(pattr,TC_PROCESS_PRIVATE);
1457
    TC_MUTEX_INIT(&(channel->ilock),rattr);
1458
    TC_COND_CREATE(&(channel->icv),pattr);
1459
    TC_MUTEX_INIT(&(channel->olock),rattr);
1460
    TC_COND_CREATE(&(channel->ocv),pattr);
1461
    g_channel_list->ChannelList[(g_channel_list->ChannelCount)] = channel;
1462
    channel->index = g_channel_list->ChannelCount;
1463
    if (g_drdynvc_arr == NULL) {
1464
      g_drdynvc_arr = g_channel_list->ChannelList;
1465
    }
1466
    g_channel_list->ChannelCount++;
1467
    channel->channel_id = reserve_channel_id() + 1;
1468
    channel->acknowledged = 0x00;
1469
    channel->ccon = trans_create(g_drdynvc_socket_type, MAX_STREAM, MAX_STREAM);
1470
    if (channel->ccon == NULL) {
1471
      TC_MUTEX_UNLOCK(mutex_channel_list);
1472
      rv = -1;
1473
    }
1474
    else {
1475
      TC_MUTEX_LOCK(channel->ccon->lock);
1476
      channel->ccon->locked = 1;
1477
      channel->ccon->sck = -1;
1478
      trans_attach(channel->ccon, in_sck);
1479
      g_tcp_set_non_blocking(in_sck);
1480
      channel->ccon->sck = in_sck;
1481
      channel->ccon->trans_data_in = &app_data_in;
1482
      channel->ccon->callback_data = channel;
1483
      channel->ccon->header_size = 24;
1484
      channel->ccon->ready = 1;
1485
      channel->ccon->running = 1;
1486
      channel->initialized = 1;
1487
      channel->ccon->locked = 0;
1488
      TC_MUTEX_UNLOCK(channel->ccon->lock);
1489
      TC_MUTEX_UNLOCK(mutex_channel_list);
1490
    }
1491
  }
1492
 end:;
1493
  MDBGLOG("drdynvc","INFO\t[%s()]: done.",__func__);
1494
  return rv;
1495
}
1496
1497
/*****************************************************************************/
1498
static ptrdiff_t APP_CC reserve_channel_id() {
1499
    ptrdiff_t rv = -1;
1500
    ptrdiff_t i = 0;
1501
    TC_MUTEX_LOCK(mutex_id);
1502
    for (i = 0; i < MAX_CHANNEL; i++) if (g_channel_ids[i] < 1) {
1503
      rv = i;
1504
      g_channel_ids[i] = 1;
1505
    }
1506
    TC_MUTEX_UNLOCK(mutex_id);
1507
    return rv;
1508
}
1509
1510
/*****************************************************************************/
1511
static ptrdiff_t APP_CC release_channel_id(ptrdiff_t id) {
1512
    ptrdiff_t rv = 0;
1513
    if (id > -1 && id < MAX_CHANNEL) {
1514
      TC_MUTEX_LOCK(mutex_id);
1515
      g_channel_ids[id] = 0;
1516
      TC_MUTEX_UNLOCK(mutex_id);
1517
    }
1518
    return rv;
1519
}
1520
1521
/*****************************************************************************/
1522
/******		Operation IDs						******/
1523
/*****************************************************************************/
1524
1525
/*****************************************************************************/
1526
static ptrdiff_t APP_CC get_opid(void * idev) {
1527
  ptrdiff_t rv = 0;
1528
  drdynvc_t * chan = (drdynvc_t *)idev;
1529
  if (chan == NULL) {
1530
    rv = -1;
1531
  }
1532
  else {
1533
    if (chan->top_opid == 0) {
1534
      chan->top_opid++;
1535
    }
1536
    rv = chan->top_opid++;
1537
    register_opid(chan, rv);
1538
  }
1539
  return rv;
1540
}
1541
1542
/*****************************************************************************/
1543
static ptrdiff_t APP_CC register_opid(void * ichan, ptrdiff_t opid) {
1544
  ptrdiff_t rv = -1;
1545
  ptrdiff_t idx = 0;
1546
  ptrdiff_t tmp = -1;
1547
  drdynvc_t * chan = (drdynvc_t *)ichan;
1548
  if (chan == NULL) {
1549
    rv = -1;
1550
  }
1551
  else {
1552
    for (idx = 0; idx < MAX_PENDING; idx++) {
1553
      if ((tmp < 0) && (chan->pending_opids[idx] == 0)) {
1554
	tmp = idx;
1555
	rv = idx;
1556
	chan->pending_opids[idx] = opid;
1557
      }
1558
      else if (chan->pending_opids[idx] == opid) {
1559
	/* ERROR: the opid is already registered */
1560
	rv = -1;
1561
	if (tmp > -1) {
1562
	  chan->pending_opids[tmp] = 0;
1563
	}
1564
	MDBGLOG("redir","ERROR\t[%s()]: \"%d\" is already registered at position %d",__func__,opid,idx);
1565
	break;
1566
      }
1567
    }
1568
  }
1569
  if (rv > -1) {
1570
    if (chan->callbacks != NULL) {
1571
      tc_t tattr;
1572
      tc_t uattr;
1573
      tc_p mattr = &tattr;
1574
      tc_p cattr = &uattr;
1575
      TC_MUTATTR_INIT(mattr);
1576
      TC_MUTATTR_SETTYPE(mattr,TC_MUTEX_ERRORCHECK);
1577
      TC_MUTATTR_SETPSHARED(mattr,TC_PROCESS_SHARED);
1578
      TC_CONDATTR_INIT(cattr);
1579
      TC_CONDATTR_SETPSHARED(cattr,TC_PROCESS_SHARED);
1580
      TC_MUTEX_INIT(&(chan->callbacks[rv].mutex),mattr);
1581
      TC_COND_CREATE(&(chan->callbacks[rv].cv),cattr);
1582
      chan->callbacks[rv].opid = opid;
1583
      chan->callbacks[rv].type = 0;
1584
      chan->callbacks[rv].channel_id = chan->channel_id;
1585
      chan->callbacks[rv].channel = chan;
1586
      chan->callbacks[rv].fd = chan->socket;
1587
      chan->callbacks[rv].trans = chan->ccon;
1588
    }
1589
    rv = 0;
1590
  }
1591
  return rv;
1592
}
1593
1594
/*****************************************************************************/
1595
static ptrdiff_t APP_CC strike_opid(void * idev, ptrdiff_t opid) {
1596
  ptrdiff_t rv = 0;
1597
  drdynvc_t * chan = (drdynvc_t *)idev;
1598
  rv = opid_is_registered(chan, opid);
1599
  if (rv > 0) {
1600
    chan->pending_opids[rv] = 0;
1601
    if (chan->callbacks != NULL) {
1602
      if (chan->callbacks[rv].data != NULL && chan->callbacks[rv].length > 0) {
1603
	g_memset(chan->callbacks[rv].data,0,chan->callbacks[rv].length);
1604
	//g_free(chan->callbacks[rv].data);
1605
	chan->callbacks[rv].data = (BYTE *)NULL;
1606
      }
1607
      g_memset(&(chan->callbacks[rv]),0,sizeof(callback));
1608
      //g_free(chan->callbacks[rv]);
1609
      //chan->callbacks[rv] = (callback *)NULL;
1610
    }
1611
  }
1612
  return rv;
1613
}
1614
1615
/*****************************************************************************/
1616
static int APP_CC opid_is_registered(void * idev, ptrdiff_t opid) {
1617
  int rv = 0;
1618
  ptrdiff_t idx = 0;
1619
  drdynvc_t * chan = (drdynvc_t *)idev;
1620
  if (chan == NULL) {
1621
    rv = -1;
1622
  }
1623
  else {
1624
    for (idx = 0; idx < MAX_PENDING; idx++) {
1625
      if (chan->pending_opids[idx] == opid) {
1626
	rv = idx;
1627
	break;
1628
      }
1629
    }
1630
  }
1631
  return rv;
1632
}
1633
1634
static inline const char * nterr_msg(uint32_t err) {
1635
    char * rv = (char *)NULL;
1636
    uint32_t i = 0x00000000;
1637
    const nterr_msg_t nterr[] = NTERRMSG_ARRAY;
1638
1639
    for (i = 0; i < (sizeof(nterr) / sizeof(nterr_msg_t)); i++) {
1640
      if (nterr[i].ntstatus == err) {
1641
	rv = (char *)(nterr[i].msg);
1642
	break;
1643
      }
1644
    }
1645
1646
    return (const char *)rv;
1647
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/drdynvc.h (+23 lines)
Line 0    Link Here 
1
2
#if !defined(DRDYNVC_H)
3
#define DRDYNVC_H
4
5
#include <stdint.h>
6
#include "defines.h"
7
#include "ntstatus.h"
8
#include "arch.h"
9
#include "parse.h"
10
#include "stream_list.h"
11
12
int APP_CC
13
drdynvc_init(void);
14
int APP_CC
15
drdynvc_deinit(void);
16
int APP_CC
17
drdynvc_data_in(struct stream *, int, int, int, int);
18
int APP_CC
19
drdynvc_get_wait_objs(tbus* objs, int* count, int* timeout);
20
int APP_CC
21
drdynvc_check_wait_objs(void);
22
23
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/fuse_i.h (+25 lines)
Line 0    Link Here 
1
/*
2
    FUSE: Filesystem in Userspace
3
    Copyright (C) 2001-2006  Miklos Szeredi <miklos@szeredi.hu>
4
5
    This program can be distributed under the terms of the GNU LGPL.
6
    See the file COPYING.LIB
7
*/
8
9
#include "fuse.h"
10
11
struct fuse_session;
12
struct fuse_chan;
13
14
struct fuse_cmd {
15
    char *buf;
16
    size_t buflen;
17
    struct fuse_chan *ch;
18
};
19
20
struct fuse_session *fuse_get_session(struct fuse *f);
21
22
struct fuse *fuse_new_common(int fd, struct fuse_args *args,
23
                             const struct fuse_operations *op,
24
                             size_t op_size, int compat);
25
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/global.h (+30 lines)
Line 0    Link Here 
1
/* GLOBAL.H - RSAREF types and constants
2
 */
3
4
/* PROTOTYPES should be set to one if and only if the compiler supports
5
  function argument prototyping.
6
The following makes PROTOTYPES default to 0 if it has not already
7
  been defined with C compiler flags.
8
 */
9
#ifndef PROTOTYPES
10
#define PROTOTYPES 0
11
#endif
12
13
/* POINTER defines a generic pointer type */
14
typedef unsigned char *POINTER;
15
16
/* UINT2 defines a two byte word */
17
typedef unsigned short int UINT2;
18
19
/* UINT4 defines a four byte word */
20
typedef unsigned int UINT4;
21
22
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
23
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
24
  returns an empty list.
25
 */
26
#if PROTOTYPES
27
#define PROTO_LIST(list) list
28
#else
29
#define PROTO_LIST(list) ()
30
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/Makefile.am (-5 / +41 lines)
 Lines 1-23    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED \
12
  -DXRDP_ENABLE_IMA_ADPCM
13
14
LDFLAGS = \
15
  -lpthread
7
16
8
INCLUDES = \
17
INCLUDES = \
9
  -I$(top_srcdir)/common
18
  -I$(top_srcdir)/common \
19
  -I/usr/lib/glib/include \
20
  -I/usr/include/glib-1.2 \
21
  -I/usr/lib/glib-1.2/include
10
22
11
sbin_PROGRAMS = \
23
sbin_PROGRAMS = \
12
  xrdp-chansrv
24
  xrdp-chansrv
13
25
14
xrdp_chansrv_SOURCES = \
26
xrdp_chansrv_SOURCES = \
27
  global.h \
15
  chansrv.c \
28
  chansrv.c \
29
  chansrv.h \
16
  sound.c \
30
  sound.c \
31
  sound.h \
17
  clipboard.c \
32
  clipboard.c \
18
  devredir.c
33
  clipboard.h \
34
  devredir.c \
35
  devredir.h \
36
  params.h \
37
  rdpdr_defs.h \
38
  rdpfs.c \
39
  fuse_i.h \
40
  rdpport.c \
41
  rdpport_defs.h \
42
  rdpprint.c \
43
  rdpsc.c \
44
  md5c.c \
45
  md5.h \
46
  drdynvc.c \
47
  drdynvc.h
19
48
20
xrdp_chansrv_LDADD = \
49
xrdp_chansrv_LDADD = \
21
  -L/usr/X11R6/lib \
50
  -L/usr/X11R6/lib \
22
  $(top_srcdir)/common/libcommon.la \
51
  $(top_builddir)/common/libcommon.la
23
  -lX11 -lXfixes
52
53
xrdp_chansrv_LDFLAGS = \
54
  -lX11 \
55
  -lXfixes \
56
  -lxcb \
57
  -lfuse \
58
  -lm \
59
  -lpulse
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/md5c.c (+312 lines)
Line 0    Link Here 
1
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
2
 */
3
4
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
5
rights reserved.
6
7
License to copy and use this software is granted provided that it
8
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9
Algorithm" in all material mentioning or referencing this software
10
or this function.
11
12
License is also granted to make and use derivative works provided
13
that such works are identified as "derived from the RSA Data
14
Security, Inc. MD5 Message-Digest Algorithm" in all material
15
mentioning or referencing the derived work.
16
17
RSA Data Security, Inc. makes no representations concerning either
18
the merchantability of this software or the suitability of this
19
software for any particular purpose. It is provided "as is"
20
without express or implied warranty of any kind.
21
22
These notices must be retained in any copies of any part of this
23
documentation and/or software.
24
 */
25
26
#include <stddef.h>
27
#include <string.h>
28
#include "global.h"
29
#include "md5.h"
30
31
/* Constants for MD5Transform routine.
32
 */
33
#define S11 7
34
#define S12 12
35
#define S13 17
36
#define S14 22
37
#define S21 5
38
#define S22 9
39
#define S23 14
40
#define S24 20
41
#define S31 4
42
#define S32 11
43
#define S33 16
44
#define S34 23
45
#define S41 6
46
#define S42 10
47
#define S43 15
48
#define S44 21
49
50
static void APP_CC MD5Transform (UINT4 [4], unsigned char [64]);
51
static void APP_CC Encode (unsigned char *, UINT4 *, size_t);
52
static void APP_CC Decode (UINT4 *, unsigned char *, size_t);
53
static inline void APP_CC MD5_memcpy (POINTER, POINTER, size_t);
54
static inline void APP_CC MD5_memset (POINTER, int, size_t);
55
56
static unsigned char PADDING[64] = {
57
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
60
};
61
62
/* F, G, H and I are basic MD5 functions.
63
 */
64
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
65
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
66
#define H(x, y, z) ((x) ^ (y) ^ (z))
67
#define I(x, y, z) ((y) ^ ((x) | (~z)))
68
69
/* ROTATE_LEFT rotates x left n bits.
70
 */
71
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
72
73
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
74
Rotation is separate from addition to prevent recomputation.
75
 */
76
#define FF(a, b, c, d, x, s, ac) { \
77
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
78
 (a) = ROTATE_LEFT ((a), (s)); \
79
 (a) += (b); \
80
  }
81
#define GG(a, b, c, d, x, s, ac) { \
82
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
83
 (a) = ROTATE_LEFT ((a), (s)); \
84
 (a) += (b); \
85
  }
86
#define HH(a, b, c, d, x, s, ac) { \
87
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
88
 (a) = ROTATE_LEFT ((a), (s)); \
89
 (a) += (b); \
90
  }
91
#define II(a, b, c, d, x, s, ac) { \
92
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
93
 (a) = ROTATE_LEFT ((a), (s)); \
94
 (a) += (b); \
95
  }
96
97
/* MD5 initialization. Begins an MD5 operation, writing a new context.
98
 */
99
void APP_CC MD5Init (MD5_CTX * context) {
100
  context->count[0] = context->count[1] = 0;
101
  /* Load magic initialization constants.
102
*/
103
  context->state[0] = 0x67452301;
104
  context->state[1] = 0xefcdab89;
105
  context->state[2] = 0x98badcfe;
106
  context->state[3] = 0x10325476;
107
}
108
109
/* MD5 block update operation. Continues an MD5 message-digest
110
  operation, processing another message block, and updating the
111
  context.
112
 */
113
void APP_CC MD5Update (MD5_CTX * context, unsigned char * input, size_t inputLen) {
114
  size_t index = 0;
115
  ptrdiff_t dindex = 0;
116
  ptrdiff_t i = 0;
117
  ptrdiff_t partLen = 0;
118
119
  /* Compute number of bytes mod 64 */
120
  index = (size_t)((context->count[0] >> 3) & 0x3F);
121
  dindex = index;
122
123
  /* Update number of bits */
124
  if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) {
125
    (context->count[1])++;
126
    context->count[1] += ((UINT4)inputLen >> 29);
127
  }
128
129
  partLen = 64 - index;
130
131
  /* Transform as many times as possible.
132
*/
133
  if (inputLen >= partLen) {
134
    MD5_memcpy((POINTER)&context->buffer[dindex], (POINTER)input, partLen);
135
    MD5Transform (context->state, context->buffer);
136
    for (i = partLen; (i + 63) < inputLen; i += 64) {
137
	MD5Transform (context->state, &(input[i]));
138
    }
139
    dindex = 0;
140
    index = 0;
141
  }
142
  else {
143
    i = 0;
144
  }
145
146
  /* Buffer remaining input */
147
  MD5_memcpy((POINTER)(&(context->buffer[dindex])), (POINTER)(&(input[i])), (inputLen - i));
148
}
149
150
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
151
  the message digest and zeroizing the context.
152
 */
153
void APP_CC MD5Final (unsigned char digest[16], MD5_CTX * context) {
154
  unsigned char bits[8] = {0, 0, 0, 0, 0, 0, 0, 0};
155
  size_t index = 0;
156
  size_t padLen = 0;
157
158
  /* Save number of bits */
159
  Encode (bits, context->count, 8);
160
161
  /* Pad out to 56 mod 64. */
162
  index = (size_t)((context->count[0] >> 3) & 0x3f);
163
  padLen = (index < 56) ? (56 - index) : (120 - index);
164
  MD5Update (context, PADDING, padLen);
165
166
  /* Append length (before padding) */
167
  MD5Update (context, bits, 8);
168
  /* Store state in digest */
169
  Encode (digest, context->state, 16);
170
171
  /* Zeroize sensitive information. */
172
  MD5_memset ((POINTER)context, 0, sizeof (*context));
173
}
174
175
/* MD5 basic transformation. Transforms state based on block.
176
 */
177
static void APP_CC MD5Transform (UINT4 state[4], unsigned char block[64]) {
178
  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
179
180
  Decode (x, block, 64);
181
182
  /* Round 1 */
183
  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
184
  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
185
  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
186
  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
187
  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
188
  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
189
  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
190
  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
191
  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
192
  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
193
  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
194
  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
195
  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
196
  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
197
  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
198
  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
199
200
 /* Round 2 */
201
  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
202
  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
203
  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
204
  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
205
  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
206
  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
207
  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
208
  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
209
  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
210
  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
211
  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
212
  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
213
  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
214
  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
215
  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
216
  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
217
218
  /* Round 3 */
219
  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
220
  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
221
  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
222
  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
223
  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
224
  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
225
  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
226
  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
227
  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
228
  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
229
  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
230
  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
231
  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
232
  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
233
  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
234
  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
235
236
  /* Round 4 */
237
  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
238
  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
239
  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
240
  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
241
  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
242
  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
243
  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
244
  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
245
  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
246
  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
247
  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
248
  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
249
  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
250
  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
251
  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
252
  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
253
254
  state[0] += a;
255
  state[1] += b;
256
  state[2] += c;
257
  state[3] += d;
258
259
  /* Zeroize sensitive information.
260
*/
261
  MD5_memset ((POINTER)x, 0, sizeof (x));
262
}
263
264
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
265
  a multiple of 4.
266
 */
267
static void APP_CC Encode (unsigned char * output, UINT4 * input, size_t len) {
268
  ptrdiff_t i = 0;
269
  ptrdiff_t j = 0;
270
271
  for (i = 0, j = 0; j < len; i++, j += 4) {
272
    output[j] = (unsigned char)(input[i] & 0xff);
273
    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
274
    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
275
    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
276
  }
277
}
278
279
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
280
  a multiple of 4.
281
 */
282
static void APP_CC Decode (UINT4 * output, unsigned char * input, size_t len) {
283
  ptrdiff_t i = 0;
284
  ptrdiff_t j = 0;
285
286
  for (i = 0, j = 0; j < len; i++, j += 4) {
287
    output[i] = ((UINT4)(input[j])) | (((UINT4)(input[(j+1)])) << 8) | (((UINT4)(input[(j+2)])) << 16) | (((UINT4)(input[(j+3)])) << 24);
288
  }
289
}
290
291
/* Note: Replace "for loop" with standard memcpy if possible.
292
 */
293
294
static inline void APP_CC MD5_memcpy (POINTER output, POINTER input, size_t len) {
295
  ptrdiff_t i = 0;
296
297
  for (i = 0; i < len; i++) {
298
    output[i] = input[i];
299
  }
300
}
301
302
/* Note: Replace "for loop" with standard memset if possible.
303
 */
304
static inline void APP_CC MD5_memset (POINTER output, int value, size_t len) {
305
  ptrdiff_t i = 0;
306
  if (1) {
307
    memset(output,value,len);
308
  }
309
  else for (i = 0; i < len; i++) {
310
    ((char *)output)[i] = (char)value;
311
  }
312
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/md5.h (+54 lines)
Line 0    Link Here 
1
/* MD5.H - header file for MD5C.C
2
 */
3
4
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
5
rights reserved.
6
7
License to copy and use this software is granted provided that it
8
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9
Algorithm" in all material mentioning or referencing this software
10
or this function.
11
12
License is also granted to make and use derivative works provided
13
that such works are identified as "derived from the RSA Data
14
Security, Inc. MD5 Message-Digest Algorithm" in all material
15
mentioning or referencing the derived work.
16
17
RSA Data Security, Inc. makes no representations concerning either
18
the merchantability of this software or the suitability of this
19
software for any particular purpose. It is provided "as is"
20
without express or implied warranty of any kind.
21
22
These notices must be retained in any copies of any part of this
23
documentation and/or software.
24
 */
25
26
#include <stddef.h>
27
#include <stdint.h>
28
29
#if !defined(UINT4)
30
#define	UINT4	uint32_t
31
#endif
32
33
#if !defined(APP_CC)
34
#define APP_CC
35
#endif
36
37
#ifdef __cplusplus
38
extern "C" {
39
#endif
40
41
/* MD5 context. */
42
typedef struct _MD5_CTX {
43
  UINT4 state[4];                                   /* state (ABCD) */
44
  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
45
  unsigned char buffer[64];                         /* input buffer */
46
} MD5_CTX;
47
48
void APP_CC MD5Init (MD5_CTX *);
49
void APP_CC MD5Update (MD5_CTX *, unsigned char *, size_t);
50
void APP_CC MD5Final (unsigned char [16], MD5_CTX *);
51
52
#ifdef __cplusplus
53
}
54
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/params.h (+29 lines)
Line 0    Link Here 
1
// There are a couple of symbols that need to be #defined before
2
// #including all the headers.
3
4
#ifndef _PARAMS_H_
5
#define _PARAMS_H_
6
7
// The FUSE API has been changed a number of times.  So, our code
8
// needs to define the version of the API that we assume.  As of this
9
// writing, the most current API version is 26
10
#define FUSE_USE_VERSION 26
11
12
// need this to get pwrite().  I have to use setvbuf() instead of
13
// setlinebuf() later in consequence.
14
#define _XOPEN_SOURCE 500
15
16
// maintain bbfs state in here
17
#include <limits.h>
18
#include <stdio.h>
19
20
#ifndef __RDPFS_STATE__
21
#define __RDPFS_STATE__
22
struct rdpfs_state {
23
    FILE *logfile;
24
    char *rootdir;
25
};
26
#define RDPFS_DATA ((struct rdpfs_state *) fuse_get_context()->private_data)
27
#endif
28
29
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/rdpfs.c (+6437 lines)
Line 0    Link Here 
1
/*
2
 *
3
 *  RDP File System for device redirection
4
 *
5
 */
6
7
#ifdef FUSE_USE_VERSION 
8
#undef FUSE_USE_VERSION
9
#endif
10
11
#define FUSE_USE_VERSION 26
12
13
#include "params.h"
14
15
#include <pthread.h>
16
#include <ctype.h>
17
#include <dirent.h>
18
#include <errno.h>
19
#include <fcntl.h>
20
#include <fuse.h>
21
#include <libgen.h>
22
#include <limits.h>
23
#include <pthread.h>
24
#include <stdint.h>
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <unistd.h>
29
#include <sys/types.h>
30
#include <sys/sysmacros.h>
31
/* #include <sys/xattr.h> */
32
33
#include "log.h"
34
#include "arch.h"
35
#include "parse.h"
36
#include "defines.h"
37
#include "rdpdr.h"
38
#include "rdpdr_methods.h"
39
#include "fuse_i.h"
40
#include "trans.h"
41
#include "devredir_defs.h"
42
#include "global.h"
43
#include "md5.h"
44
#include "thread_calls.h"
45
#include "thread_macros.h"
46
#include "crc32.h"
47
#include "dbg.h"
48
49
50
//#if defined(MDBGLOG)
51
//#undef MDBGLOG
52
//#define MDBGLOG(...)    ;
53
//#endif
54
55
56
#ifndef MAX_REQID
57
#define MAX_REQID	25
58
#endif
59
60
61
extern int g_fs_count;
62
extern char * APP_CC ntstatus_string(uint32_t);
63
64
65
static rdpfs * g_rdpfs = (rdpfs *)NULL;
66
static rdpfs ** g_fs_arr = (rdpfs **)NULL;
67
static tc_p mutex_fs_arr = (tc_p)NULL;
68
69
static tc_p mutex_pcon_fs = (tc_p)NULL;
70
static tc_p mutex_fs = (tc_p)NULL;
71
static tc_p mutex_parent_fs = (tc_p)NULL;
72
static tc_p mutex_fuse = (tc_p)NULL;
73
static tc_p mutex_fsop = (tc_p)NULL;
74
static tc_p mutex_reqid_fs = (tc_p)NULL;
75
static tc_p mutex_getattr = (tc_p)NULL;
76
static tc_p cv_readdir = (tc_p)NULL;
77
78
static struct _rdpstat {
79
	unsigned char		set;
80
	char			path[255];
81
	struct stat		st;
82
} g_fattr_cache[MAX_REQID] = { };
83
84
static int APP_CC rdpfs_open(const char *, struct fuse_file_info *);
85
static int APP_CC rdpfs_open_args(const char *, struct fuse_file_info *, uint32_t, uint32_t, uint32_t, uint32_t);
86
static int APP_CC rdpfs_getattr(const char *, struct stat *);
87
static int APP_CC rdpfs_fgetattr(const char *, struct stat *, struct fuse_file_info *);
88
static int APP_CC rdpfs_release(const char *, struct fuse_file_info *);
89
static int APP_CC rdpfs_read_chunk(const char *, char *, size_t, off_t, struct fuse_file_info *);
90
static int APP_CC rdpfs_create(const char *, mode_t, struct fuse_file_info *);
91
static int APP_CC rdpfs_create_args(const char *, mode_t, struct fuse_file_info *, uint32_t, uint32_t, uint32_t, uint32_t);
92
static int APP_CC rdpfs_mkdir(const char *, mode_t);
93
static int APP_CC rdpfs_write_chunk(const char *, const char *, size_t, off_t, struct fuse_file_info *);
94
static int APP_CC rdpfs_releasedir(const char *, struct fuse_file_info *);
95
static int APP_CC rdpfs_write(const char *, const char *, size_t, off_t, struct fuse_file_info *);
96
static int APP_CC rdpfs_ftruncate(const char *, off_t, struct fuse_file_info *);
97
static int APP_CC rdpfs_fsctl(const char *, struct fuse_file_info *, DWORD, int, void *);
98
99
static int APP_CC get_reqid_fs(int *);
100
static int APP_CC free_reqid_fs(int);
101
static int APP_CC init_reqids_fs(rdpfs *);
102
static int APP_CC get_mutex_fs(int, tc_p *, rdpfs *);
103
static int APP_CC get_cv_fs(int, tc_p *, rdpfs *);
104
static int APP_CC get_cbdata_fs(int reqid, callback **);
105
static int APP_CC ntstatus_to_errcode(DWORD);
106
static APP_CC int rdpfs_parse_path(const char *, char **, char **);
107
108
static int APP_CC construct_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK *);
109
static char * APP_CC get_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK *);
110
static int APP_CC set_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK *, const char *);
111
static int APP_CC input_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK *, struct stream *);
112
static int APP_CC send_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK *, struct stream *);
113
114
static int APP_CC send_INTERIX_DEV_FILE(INTERIX_DEV_FILE *, struct stream *);
115
static int APP_CC set_INTERIX_DEV_FILE(INTERIX_DEV_FILE *, char, int64_t, int64_t);
116
static int APP_CC construct_INTERIX_DEV_FILE(INTERIX_DEV_FILE *);
117
118
static size_t APP_CC parent_data_in(struct trans *);
119
120
static struct fuse * rdpfs_setup_common(int argc, char *argv[],
121
                                      const struct fuse_operations *,
122
                                      size_t,
123
                                      char **,
124
                                      int *,
125
                                      int *,
126
				      struct fuse_chan **,
127
                                      int,
128
				      struct rdpfs_state *);
129
130
static const struct fuse_opt fuse_helper_opts[] = {
131
    FUSE_HELPER_OPT("-d",          foreground),
132
    FUSE_HELPER_OPT("debug",       foreground),
133
    FUSE_HELPER_OPT("-f",          foreground),
134
    FUSE_HELPER_OPT("-s",          singlethread),
135
    FUSE_HELPER_OPT("fsname=",     fsname),
136
137
    FUSE_OPT_KEY("-h",          KEY_HELP),
138
    FUSE_OPT_KEY("--help",      KEY_HELP),
139
    FUSE_OPT_KEY("-ho",         KEY_HELP_NOHEADER),
140
    FUSE_OPT_KEY("-V",          KEY_VERSION),
141
    FUSE_OPT_KEY("--version",   KEY_VERSION),
142
    FUSE_OPT_KEY("-d",          KEY_KEEP),
143
    FUSE_OPT_KEY("debug",       KEY_KEEP),
144
    FUSE_OPT_KEY("fsname=",     KEY_KEEP),
145
    FUSE_OPT_END
146
};
147
148
static int rdpfs_parse_cmdline(struct fuse_args *args, char **mountpoint,
149
                       int *multithreaded, int *foreground);
150
151
static int rdpfs_readlink(const char *, char *, size_t);
152
153
/* Report errors to logfile and give -errno to caller	*/
154
static int rdpfs_error(char * str) {
155
    int ret = -errno;
156
157
    MDBGLOG("rdpfs","    %s: %s\n", str, strerror(errno));
158
159
    return ret;
160
}
161
162
static void rdpfs_fullpath(char fpath[PATH_MAX], const char * path) {
163
    if (fpath != NULL && path != NULL) {
164
      g_snprintf(fpath,(PATH_MAX - 1),"%s",path);
165
    }
166
}
167
168
static int rdpfs_is_symlink(const char * path) {
169
    int retstat = 0;
170
    char * fpath = (char *)NULL;
171
    ptrdiff_t rlen = 0;
172
    char lpath[PATH_MAX] = "";
173
174
    g_memset(lpath,0,sizeof(char)*PATH_MAX);
175
176
    fpath = (char *)g_strdup(path);
177
    rlen = rdpfs_readlink(fpath,lpath,PATH_MAX);
178
    if (rlen > -1 && g_strlen(lpath) > 0) {
179
      retstat = 1;
180
    }
181
    else {
182
      retstat = 0;
183
    }
184
185
    if (retstat > 0) {
186
      MDBGLOG("rdpfs","* \"%s\" IS a symlink",path);
187
    }
188
    else {
189
      MDBGLOG("rdpfs","* \"%s\" is NOT a symlink",path);
190
    }
191
192
    if (fpath != NULL && g_strlen(fpath) > 0) {
193
      g_free(fpath);
194
    }
195
196
    return retstat;
197
}
198
199
static int rdpfs_is_blk_file(const char * path) {
200
    int retstat = 0;
201
    char * fpath = (char *)NULL;
202
    size_t tsize = 24;
203
    off_t toffset = 0;
204
    ptrdiff_t rlen = 0;
205
    char lpath[PATH_MAX];
206
    struct fuse_file_info lfi;
207
    struct fuse_file_info * fi = &lfi;
208
    INTERIX_DEV_FILE ldf;
209
    INTERIX_DEV_FILE * df = &ldf;
210
    LOCAL_STREAM(s);
211
212
    g_memset(lpath,0,sizeof(char)*PATH_MAX);
213
    g_memset(&ldf,0,sizeof(INTERIX_DEV_FILE));
214
    g_memset(&lfi,0,sizeof(struct fuse_file_info));
215
    fi->flags |= O_RDONLY;
216
217
    fpath = (char *)g_strdup(path);
218
    rlen = rdpfs_open(fpath, fi);
219
    if (rlen < 0) {
220
      retstat = rlen;
221
      goto rel_tag;
222
    }
223
    rdpfs_read_chunk(fpath,(char *)(s->data),tsize,toffset,fi);
224
    s->p += tsize;
225
    s_mark_end(s);
226
    s->p = s->data;
227
    in_uint8a(s, df->magic, 8);
228
    in_uint64_le(s, df->major);
229
    in_uint64_le(s, df->minor);
230
231
    if (df != NULL && df->magic != NULL &&  df->magic[0] == 'I' && df->magic[1] == 'n' && df->magic[2] == 't' && df->magic[3] == 'x' && df->magic[4] == 'B' && df->magic[5] == 'L' && df->magic[6] == 'K' && df->magic[7] == '\0') {
232
      int tmaj = df->major;
233
      int tmin = df->minor;
234
      retstat = makedev(tmaj,tmin);
235
    }
236
    else {
237
      retstat = 0;
238
    }
239
240
    if (retstat > 0) {
241
      MDBGLOG("rdpfs","* \"%s\" IS a block device",path);
242
    }
243
    else {
244
      MDBGLOG("rdpfs","* \"%s\" is NOT a block device",path);
245
    }
246
247
  rel_tag:
248
    if (fpath != NULL && g_strlen(fpath) > 0 && fi != NULL && fi->fh > 0) {
249
      rdpfs_release(fpath,fi);
250
    }
251
252
    if (fpath != NULL && g_strlen(fpath) > 0) {
253
      g_free(fpath);
254
    }
255
256
    return retstat;
257
}
258
259
static int rdpfs_is_chr_file(const char * path) {
260
    int retstat = 0;
261
    char * fpath = (char *)NULL;
262
    size_t tsize = 24;
263
    off_t toffset = 0;
264
    ptrdiff_t rlen = 0;
265
    char lpath[PATH_MAX] = "";
266
    struct fuse_file_info lfi;
267
    struct fuse_file_info * fi = &lfi;
268
    INTERIX_DEV_FILE ldf;
269
    INTERIX_DEV_FILE * df = &ldf;
270
    LOCAL_STREAM(s);
271
272
    g_memset(lpath,0,sizeof(char)*PATH_MAX);
273
    g_memset(&ldf,0,sizeof(INTERIX_DEV_FILE));
274
    g_memset(&lfi,0,sizeof(struct fuse_file_info));
275
    fi->flags |= O_RDONLY;
276
277
    fpath = (char *)g_strdup(path);
278
    rlen = rdpfs_open(fpath, fi);
279
    if (rlen < 0) {
280
      retstat = rlen;
281
      goto rel_tag;
282
    }
283
    rlen = rdpfs_read_chunk(fpath,(char *)(s->data),tsize,toffset,fi);
284
    if (rlen != 24) {
285
      retstat = -1;
286
      goto rel_tag;
287
    }
288
    s->p += tsize;
289
    s_mark_end(s);
290
    s->p = s->data;
291
    in_uint8a(s, df->magic, 8);
292
    in_uint64_le(s, df->major);
293
    in_uint64_le(s, df->minor);
294
295
    if (df != NULL && df->magic != NULL &&  df->magic[0] == 'I' && df->magic[1] == 'n' && df->magic[2] == 't' && df->magic[3] == 'x' && df->magic[4] == 'C' && df->magic[5] == 'H' && df->magic[6] == 'R' && df->magic[7] == '\0') {
296
      int tmaj = df->major;
297
      int tmin = df->minor;
298
      retstat = makedev(tmaj,tmin);
299
    }
300
    else {
301
      retstat = 0;
302
    }
303
304
    if (retstat > 0) {
305
      MDBGLOG("rdpfs","* \"%s\" IS a character device",path);
306
    }
307
    else {
308
      MDBGLOG("rdpfs","* \"%s\" is NOT a character device",path);
309
    }
310
311
  rel_tag:;
312
    if (fpath != NULL && g_strlen(fpath) > 0 && fi != NULL && fi->fh > 0) {
313
      rdpfs_release(fpath,fi);
314
    }
315
316
    if (fpath != NULL && g_strlen(fpath) > 0) {
317
      g_free(fpath);
318
    }
319
320
    return retstat;
321
}
322
323
/** Get file attributes.
324
 *
325
 * Similar to stat().  The 'st_dev' and 'st_blksize' fields are
326
 * ignored.  The 'st_ino' field is ignored except if the 'use_ino'
327
 * mount option is given.
328
 */
329
int rdpfs_getattr(const char * ipath, struct stat * statbuf) {
330
    RDPFS_DECS;
331
    int retstat = 0;
332
    //tbus fd = -1;
333
    DIR * dp = (DIR *)NULL;
334
    char fpath[PATH_MAX] = "";
335
    struct stream * s = NULL;
336
    char buf[512] = "";
337
    struct stat st;
338
    ptrdiff_t ldx = 0;
339
    struct trans * pcon = (struct trans *)NULL;
340
    int rdpfs_opcode = 0x00000000;
341
    ptrdiff_t size = 0x00000000;
342
    int reqid = -1;
343
    tbus fhandle = 0;
344
    int uniqid = 0;
345
    struct fuse_file_info * lfi = NULL;
346
    tc_p lmutex = (tc_p)NULL;
347
    tc_p lcv = (tc_p)NULL;
348
    callback * cbdata = NULL;
349
    filelist_entry * finfo = NULL;
350
    char * path = (char *)NULL;
351
    char * tstream = (char *)NULL;
352
    const uint32_t magic = RDP_PACKET_MAGIC;
353
    uint32_t crc32 = 0;
354
    unsigned char cached = 0;
355
356
    MDBGLOG("rdpfs","\nINFO\t[%s()]: called (ipath=\"%s\", statbuf=0x%8.8x)\n",__func__,ipath,statbuf);
357
358
    g_memset(&st,0,sizeof(struct stat));
359
    g_memset(fpath,0,sizeof(fpath));
360
    g_memset(buf,0,sizeof(buf));
361
362
    rdpfs_parse_path(ipath, &path, &tstream);
363
364
    /*
365
     *  Check whether the target path is already in the cache:
366
     */
367
    if (g_strlen(path) > 0) for (ldx = 0; ldx < MAX_REQID; ldx++) {
368
      if (g_fattr_cache[ldx].set > 0 && !g_strncmp(g_fattr_cache[ldx].path,path,255)) {
369
	cached = 1;
370
	goto bypass;
371
      }
372
    }
373
    ldx = 0;
374
375
    lfi = (struct fuse_file_info *)g_malloc(sizeof(struct fuse_file_info), 1);
376
    rdpfs_open(path, lfi);
377
    dp = (DIR *)(uintptr_t)(lfi->fh);
378
    fhandle = (int)(uintptr_t)dp;
379
380
    /*	Odd bug: it is necessary to close the just-opened file,
381
     *  and then re-open it, in order to prevent a wierd off-by-one
382
     *  error in directory listings.  This probably has something to
383
     *  do with the need to flush the filesystem cache or something
384
     *  like that...
385
     */
386
387
    TC_MUTEX_LOCK(mutex_fsop);
388
    get_reqid_fs(&reqid);
389
    get_mutex_fs(reqid,(tc_p *)&lmutex,g_fs);
390
    TC_MUTEX_LOCK(lmutex);
391
    TC_MUTEX_UNLOCK(mutex_fsop);
392
393
    rdpfs_opcode = RDPFS_GETATTR;
394
    rdpfs_fullpath(fpath, path);
395
    size = g_strlen(fpath) + 1;
396
    uniqid = reqid;
397
398
    cbdata = &(g_reqids[reqid]);
399
    cbdata->userdata = (BYTE *)g_malloc(sizeof(filelist_entry), 1);
400
    cbdata->uniqid = uniqid;
401
    cbdata->FileId = fhandle;
402
403
    if (size > 0 && fpath != NULL) {
404
      crc32 = Crc32_ComputeBuf(0, fpath, size);
405
    }
406
407
    TC_MUTEX_LOCK(mutex_pcon_fs);
408
    pcon = g_fs->ccon;
409
    pcon->callback_data = cbdata;
410
    s = trans_get_out_s(pcon, MAX_STREAM);
411
    out_uint32_le(s, magic);
412
    out_uint32_le(s, rdpfs_opcode);
413
    out_uint32_le(s, size);
414
    out_uint32_le(s, device_id);
415
    out_uint32_le(s, fhandle);
416
    out_uint32_le(s, uniqid);
417
    out_uint32_le(s, crc32);
418
    if (size > 0) {
419
      out_uint8a(s, fpath, size);
420
    }
421
    s_mark_end(s);
422
    size = s->end - s->data;
423
424
    MDBGLOG("rdpfs"," ** rdpfs_getattr(): sending [g_fd = %d; pcon->sck = %d; FileId = %d; uniqid = %d]", g_fd, pcon->sck, cbdata->FileId, cbdata->uniqid);
425
    trans_force_write(pcon);
426
    g_memset(s->data,0,MAX_STREAM);
427
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
428
    MDBGLOG("rdpfs","sent.");
429
430
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
431
    get_cv_fs(reqid,&lcv,g_fs);
432
    TC_COND_WAIT(lcv, lmutex);
433
    MDBGLOG("rdpfs","g_obj_wait loop: exited.");
434
435
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
436
    if (retstat < 0) {
437
	char * nterr = (char *)NULL;
438
	nterr = ntstatus_string(cbdata->IoStatus.Value);
439
	MDBGLOG("rdpfs","ERROR\t[%s()]: \"%s\" (retstat = %d; cbdata->IoStatus.Value = 0x%8.8x)",__func__,nterr,retstat,cbdata->IoStatus.Value);
440
	//g_free(nterr);
441
	goto end;
442
    }
443
444
    finfo = (filelist_entry *)(cbdata->userdata);
445
    g_memset(statbuf,0,sizeof(struct stat));
446
    statbuf->st_dev   = 0x00000801;
447
    statbuf->st_nlink = finfo->NumberOfLinks;
448
    statbuf->st_ctime = FileTimeToUnix(finfo->CreationTime);
449
    statbuf->st_mtime = FileTimeToUnix(finfo->LastWriteTime);
450
    statbuf->st_atime = FileTimeToUnix(finfo->LastAccessTime);
451
    statbuf->st_size = finfo->EndOfFile;
452
    statbuf->st_blocks = finfo->AllocationSize;
453
    statbuf->st_uid   = 0;
454
    statbuf->st_gid   = 0;
455
    if ((finfo->FileAttributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) {
456
      statbuf->st_mode = 0644;
457
    }
458
    else {
459
      statbuf->st_mode = 0755;
460
    }
461
    if ((finfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY || finfo->Directory > 0) {
462
      /*
463
       * if the above test is true, then this is a directory:
464
       */
465
      statbuf->st_mode |= S_IFDIR;
466
    }
467
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && rdpfs_is_blk_file(fpath) > 0) {
468
      /*
469
       * if the above test is true, then this is an Interix-type block device file:
470
       */
471
      statbuf->st_mode |= S_IFBLK;
472
      statbuf->st_rdev |= rdpfs_is_blk_file(fpath);
473
      statbuf->st_size = 0;
474
      statbuf->st_blocks = 0;
475
    }
476
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && rdpfs_is_chr_file(fpath) > 0) {
477
      /*
478
       * if the above test is true, then this is an Interix-type character device file:
479
       */
480
      statbuf->st_mode |= S_IFCHR;
481
      statbuf->st_rdev |= rdpfs_is_chr_file(fpath);
482
      statbuf->st_size = 0;
483
      statbuf->st_blocks = 0;
484
    }
485
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && finfo->EndOfFile > 5 && finfo->EndOfFile < 2048 && rdpfs_is_symlink(fpath) > 0) {
486
      /*
487
       * if the above test is true, then this is a "Minshall-French"-type symlink:
488
       */
489
      statbuf->st_mode |= S_IFLNK;
490
    }
491
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && finfo->EndOfFile == 0) {
492
      /*
493
       * if the above test is true, then this is an Interix-style FIFO (named pipe):
494
       */
495
      statbuf->st_mode |= S_IFIFO;
496
      statbuf->st_size = 0;
497
      statbuf->st_blocks = 0;
498
    }
499
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && finfo->EndOfFile == 1) {
500
      /*
501
       * if the above test is true, then this is an Interix-style socket:
502
       */
503
      statbuf->st_mode |= S_IFSOCK;
504
      statbuf->st_size = 0;
505
      statbuf->st_blocks = 0;
506
    }
507
    else {
508
      statbuf->st_mode |= S_IFREG;
509
    }
510
511
    MDBGLOG("rdpfs","\n\n ****** path = \"%s\"; fhandle = %d; finfo->Directory = %d; finfo->FileAttributes = 0x%8.8x\n",path,fhandle,finfo->Directory,finfo->FileAttributes);
512
513
  bypass:;
514
515
    if (cached) {
516
      MDBGLOG("rdpfs","\n*** cached! path = \"%s\"",path);
517
      g_memcpy(statbuf, &(g_fattr_cache[ldx].st), sizeof(struct stat));
518
    }
519
    else for (ldx = 0; ldx < MAX_REQID; ldx++) if (!(g_fattr_cache[ldx].set)) {
520
      g_memcpy(&(g_fattr_cache[ldx].st), statbuf, sizeof(struct stat));
521
      g_fattr_cache[ldx].set = 1;
522
    }
523
524
  end:;
525
526
    if (cbdata->userdata != NULL) {
527
      g_free(cbdata->userdata);
528
    }
529
    if (lfi != NULL && lfi->fh > 0) {
530
      rdpfs_release(path, lfi);
531
    }
532
    if (lfi != NULL) {
533
      g_free(lfi);
534
    }
535
    g_memset(cbdata,0,sizeof(callback));
536
537
    TC_MUTEX_UNLOCK(lmutex);
538
    free_reqid_fs(reqid);
539
540
    return retstat;
541
}
542
543
/** Read the target of a symbolic link
544
 *
545
 * The buffer should be filled with a null terminated string.  The
546
 * buffer size argument includes the space for the terminating
547
 * null character.  If the linkname is too long to fit in the
548
 * buffer, it should be truncated.  The return value should be 0
549
 * for success.
550
 */
551
// the description given above doesn't correspond to the readlink(2)
552
// man page -- according to that, if the link is too long for the
553
// buffer, it ends up without the null termination
554
static int rdpfs_readlink(const char * ipath, char * ilink, size_t size) {
555
    RDPFS_DECS;
556
    int retstat = 0;
557
    ptrdiff_t tsize = 0;
558
    size_t fsize = 0;
559
    off_t foffset = 0;
560
    struct stream ls;
561
    struct stream * qs = &ls;
562
    BYTE buf[MAX_STREAM];
563
    char * path = (char *)NULL;
564
    char * link = (char *)NULL;
565
    char * tlink = (char *)NULL;
566
    struct stat lsb;
567
    struct stat * sb = &lsb;
568
    struct fuse_file_info lfi;
569
    struct fuse_file_info * fi = &lfi;
570
    MINSHALL_FRENCH_SYMLINK mfsl;
571
    MINSHALL_FRENCH_SYMLINK * sl = &mfsl;
572
    char fpath[PATH_MAX];
573
    ptrdiff_t tret = 0;
574
575
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
576
577
    if (ipath != NULL && ipath[0] != '\0') {
578
      path = (char *)g_strdup(ipath);
579
      link = (char *)ilink;
580
    }
581
    else {
582
      retstat = -1;
583
      goto end_tag;
584
    }
585
586
    MDBGLOG("rdpfs","rdpfs_readlink(path=\"%s\", link=\"%s\", size=%d)\n", path, link, size);
587
588
    g_memset(fi,0,sizeof(struct fuse_file_info));
589
    g_memset(sb,0,sizeof(struct stat));
590
    g_memset(qs,0,sizeof(struct stream));
591
    g_memset(buf,0,sizeof(BYTE) * MAX_STREAM);
592
593
    qs->data = (char *)buf;
594
    qs->size = fsize;
595
    qs->p = qs->data;
596
597
    construct_MINSHALL_FRENCH_SYMLINK(sl);
598
    fi->flags |= O_RDONLY;
599
    rdpfs_open(path,fi);
600
    if (fi == NULL || fi->fh < 1) {
601
      retstat = -1;
602
      goto end_tag;
603
    }
604
    rdpfs_fullpath(fpath,path);
605
    fsize = 4096;
606
    qs->end = qs->data + fsize;
607
    tret = rdpfs_read_chunk(fpath,(char *)buf,fsize,foffset,fi);
608
    if (tret < 0) {
609
      retstat = tret;
610
      goto end_tag;
611
    }
612
    input_MINSHALL_FRENCH_SYMLINK(sl, qs);
613
    tlink = get_MINSHALL_FRENCH_SYMLINK(sl);
614
    tsize = g_strlen(tlink);
615
    if (tsize < 1) {
616
      retstat = -1;
617
    }
618
    else {
619
      g_strncpy(link,tlink,MIN(tsize,size));
620
    }
621
    if (tlink != NULL && tsize > 0) {
622
      g_free(tlink);
623
      tlink = (char *)NULL;
624
    }
625
626
    if (fi != NULL && fi->fh > 0) {
627
      rdpfs_release(path,fi);
628
    }
629
630
  end_tag:
631
    if (path != NULL && g_strlen(path) > 0) {
632
      path = NULL;
633
    }
634
    return retstat;
635
}
636
637
/** Create a file node
638
 *
639
 * There is no create() operation; instead, mknod() will be called
640
 * for creation of any non-directory, non-symlink nodes.
641
 */
642
// shouldn't that comment be "if" there is no.... ?
643
int rdpfs_mknod(const char * path, mode_t mode, dev_t dev) {
644
    RDPFS_DECS;
645
    int retstat = 0;
646
    size_t tsize = 0;
647
    off_t toffset = 0;
648
    uint32_t pflags = 0x00000000;
649
    uint32_t pshare = 0x00000000;
650
    uint32_t poptions = 0x00000000;
651
    uint32_t pattributes = 0x00000000;
652
    char fpath[PATH_MAX];
653
    struct fuse_file_info lfi;
654
    struct fuse_file_info * fi = &lfi;
655
    INTERIX_DEV_FILE ldf;
656
    INTERIX_DEV_FILE * df = &ldf;
657
    LOCAL_STREAM(s);
658
659
    MDBGLOG("rdpfs","\nrdpfs_mknod(path=\"%s\", mode=0%3o, dev=%lld)\n", path, mode, dev);
660
661
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
662
    g_memset(&lfi,0,sizeof(struct fuse_file_info));
663
    g_memset(&ldf,0,sizeof(INTERIX_DEV_FILE));
664
665
    pflags |= FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES;
666
    pshare |= (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
667
    poptions |= FILE_NON_DIRECTORY_FILE;
668
669
    fi->flags |= O_WRONLY;
670
    rdpfs_fullpath(fpath,path);
671
    if (S_ISBLK(mode)) {
672
      int64_t dmajor = major(dev);
673
      int64_t dminor = minor(dev);
674
      construct_INTERIX_DEV_FILE(df);
675
      set_INTERIX_DEV_FILE(df, 'b', dmajor, dminor);
676
      send_INTERIX_DEV_FILE(df, s);
677
      s_mark_end(s);
678
      tsize = s->end - s->data;
679
      toffset = 0;
680
      pattributes |= FILE_ATTRIBUTE_SYSTEM;
681
      retstat = rdpfs_create_args(fpath,mode,fi,pflags,pshare,poptions,pattributes);
682
      rdpfs_write_chunk(fpath,s->data,tsize,toffset,fi);
683
    }
684
    else if (S_ISCHR(mode)) {
685
      int64_t dmajor = major(dev);
686
      int64_t dminor = minor(dev);
687
      construct_INTERIX_DEV_FILE(df);
688
      set_INTERIX_DEV_FILE(df, 'c', dmajor, dminor);
689
      send_INTERIX_DEV_FILE(df, s);
690
      s_mark_end(s);
691
      tsize = s->end - s->data;
692
      toffset = 0;
693
      pattributes |= FILE_ATTRIBUTE_SYSTEM;
694
      retstat = rdpfs_create_args(fpath,mode,fi,pflags,pshare,poptions,pattributes);
695
      rdpfs_write_chunk(fpath,s->data,tsize,toffset,fi);
696
    }
697
    else if (S_ISFIFO(mode)) {
698
      tsize = 0;
699
      toffset = 0;
700
      pattributes |= FILE_ATTRIBUTE_SYSTEM;
701
      retstat = rdpfs_create_args(fpath,mode,fi,pflags,pshare,poptions,pattributes);
702
    }
703
    else if (S_ISSOCK(mode)) {
704
      tsize = 1;
705
      toffset = 0;
706
      pattributes |= FILE_ATTRIBUTE_SYSTEM;
707
      retstat = rdpfs_create_args(fpath,mode,fi,pflags,pshare,poptions,pattributes);
708
      rdpfs_write_chunk(fpath,s->data,tsize,toffset,fi);
709
    }
710
    else if (S_ISDIR(mode)) {
711
      retstat = rdpfs_mkdir(fpath,mode);
712
    }
713
    else if (S_ISREG(mode)) {
714
      pattributes = FILE_ATTRIBUTE_NORMAL;
715
      retstat = rdpfs_create(fpath,mode,fi);
716
    }
717
718
    if (fi != NULL && fi->fh > 0) {
719
      rdpfs_release(fpath,fi);
720
    }
721
722
    return retstat;
723
}
724
725
/** Create a directory */
726
static int rdpfs_mkdir(const char *path, mode_t mode) {
727
    RDPFS_DECS;
728
    //tbus fd = -1;
729
    int retstat = 0;
730
    char fpath[PATH_MAX];
731
    struct stream * s = NULL;
732
    //struct stat st;
733
    //ptrdiff_t idx = 0;
734
    //tbus objs[1] = { 0x00000000 };
735
    //size_t num_objs = 0;
736
    ptrdiff_t fsize = 0;
737
    struct trans * pcon = (struct trans *)NULL;
738
    int rdpfs_opcode = 0x00000000;
739
    int reqid = -1;
740
    tbus fhandle = 0;
741
    int uniqid = 0;
742
    //tbus empty_fi = 0;
743
    DR_DRIVE_CREATE_RSP iorsp;
744
    struct fuse_file_info tfi;
745
    struct fuse_file_info * lfi = NULL;
746
    tc_p lmutex = (tc_p)NULL;
747
    tc_p lcv = (tc_p)NULL;
748
    callback * cbdata = NULL;
749
    const uint32_t magic = RDP_PACKET_MAGIC;
750
    uint32_t crc32 = 0;
751
752
    TC_MUTEX_LOCK(mutex_fsop);
753
    get_reqid_fs(&reqid);
754
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
755
    TC_MUTEX_LOCK(lmutex);
756
    TC_MUTEX_UNLOCK(mutex_fsop);
757
758
    MDBGLOG("rdpfs","\nrdpfs_mkdir(path=\"%s\", mode = %d)\n", path, mode);
759
760
    lfi = &tfi;
761
    g_memset(&iorsp,0,sizeof(DR_DRIVE_CREATE_RSP));
762
    g_memset(lfi,0,sizeof(struct fuse_file_info));
763
764
    cbdata = &(g_reqids[reqid]);
765
    cbdata->userdata = (void *)(&iorsp);
766
    rdpfs_fullpath(fpath,path);
767
768
    rdpfs_opcode = RDPFS_MKDIR;
769
    fsize = g_strlen(fpath) + 1;
770
    uniqid = reqid;
771
772
    if (fsize > 0 && fpath != NULL) {
773
      crc32 = Crc32_ComputeBuf(0, fpath, fsize);
774
    }
775
776
    TC_MUTEX_LOCK(mutex_pcon_fs);
777
    pcon = g_fs->ccon;
778
    pcon->callback_data = cbdata;
779
    s = trans_get_out_s(pcon, MAX_STREAM);
780
    out_uint32_le(s, magic);
781
    out_uint32_le(s, rdpfs_opcode);
782
    out_uint32_le(s, fsize);
783
    out_uint32_le(s, device_id);
784
    out_uint32_le(s, fhandle);
785
    out_uint32_le(s, uniqid);
786
    out_uint32_le(s, crc32);
787
    if (fsize > 0) {
788
      out_uint8a(s, fpath, fsize);
789
    }
790
    s_mark_end(s);
791
    MDBGLOG("rdpfs"," ** rdpfs_mkdir (about to send! fsize = %d; fpath = %s)", fsize, fpath);
792
    fsize = s->end - s->data;
793
    trans_force_write(pcon);
794
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
795
    MDBGLOG("rdpfs","sent.");
796
797
    MDBGLOG("rdpfs"," Entering wait loop...");
798
    get_cv_fs(reqid,&lcv,g_fs);
799
    TC_COND_WAIT(lcv,lmutex);
800
    MDBGLOG("rdpfs"," Finished.");
801
802
    lfi->fh = cbdata->FileId;
803
    rdpfs_releasedir(path,lfi);
804
805
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
806
    if (retstat < 0) {
807
      MDBGLOG("rdpfs","ERROR [rdpfs_mkdir()]: cbdata->IoStatus.Value = 0x%8.8x; retstat = %d",cbdata->IoStatus.Value,retstat);
808
    }
809
    g_memset(cbdata,0,sizeof(callback));
810
811
    TC_MUTEX_UNLOCK(lmutex);
812
    free_reqid_fs(reqid);
813
814
    return retstat;
815
}
816
817
/** Remove a file */
818
int rdpfs_unlink(const char * path) {
819
    RDPFS_DECS;
820
    //tbus fd = -1;
821
    int retstat = 0;
822
    char fpath[PATH_MAX];
823
    struct stream * s = NULL;
824
    //struct stat st;
825
    //ptrdiff_t idx = 0;
826
    //tbus objs[1] = { 0x00000000 };
827
    //size_t num_objs = 0;
828
    ptrdiff_t fsize = 0;
829
    struct trans * pcon = (struct trans *)NULL;
830
    int rdpfs_opcode = 0x00000000;
831
    int reqid = -1;
832
    tbus fhandle = 0;
833
    int uniqid = 0;
834
    //tbus empty_fi = 0;
835
    uint32_t pflags = 0x00000000;
836
    uint32_t pshare = 0x00000000;
837
    uint32_t poptions = 0x00000000;
838
    uint32_t pattributes = 0x00000000;
839
    uint32_t crc32 = 0;
840
    const uint32_t magic = RDP_PACKET_MAGIC;
841
    tc_p lmutex = (tc_p)NULL;
842
    tc_p lcv = (tc_p)NULL;
843
    callback * cbdata = NULL;
844
    struct fuse_file_info tfi;
845
    struct fuse_file_info * lfi = &tfi;
846
847
    TC_MUTEX_LOCK(mutex_fsop);
848
    get_reqid_fs(&reqid);
849
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
850
    TC_MUTEX_LOCK(lmutex);
851
    TC_MUTEX_UNLOCK(mutex_fsop);
852
853
    MDBGLOG("rdpfs","\nrdpfs_unlink(path=\"%s\")\n", path);
854
855
    g_memset(&tfi,0,sizeof(struct fuse_file_info));
856
857
    cbdata = &(g_reqids[reqid]);
858
    rdpfs_fullpath(fpath,path);
859
    rdpfs_opcode = RDPFS_UNLINK;
860
    fsize = g_strlen(fpath) + 1;
861
    uniqid = reqid;
862
863
    pflags |= DELETE;
864
    pshare |= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
865
    //poptions |= FILE_DELETE_ON_CLOSE;
866
    rdpfs_open_args(fpath,lfi,pflags,pshare,poptions,pattributes);
867
    fhandle = lfi->fh;
868
869
    if (fsize > 0 && fpath != NULL) {
870
      crc32 = Crc32_ComputeBuf(0, fpath, fsize);
871
    }
872
873
    TC_MUTEX_LOCK(mutex_pcon_fs);
874
    pcon = g_fs->ccon;
875
    pcon->callback_data = cbdata;
876
    s = trans_get_out_s(pcon, MAX_STREAM);
877
    out_uint32_le(s, magic);
878
    out_uint32_le(s, rdpfs_opcode);
879
    out_uint32_le(s, fsize);
880
    out_uint32_le(s, device_id);
881
    out_uint32_le(s, fhandle);
882
    out_uint32_le(s, uniqid);
883
    out_uint32_le(s, crc32);
884
    if (fsize > 0) {
885
      out_uint8a(s, fpath, fsize);
886
    }
887
    s_mark_end(s);
888
    MDBGLOG("rdpfs"," ** rdpfs_unlink (about to send! fsize = %d; fpath = %s)", fsize, fpath);
889
    fsize = s->end - s->data;
890
    trans_force_write(pcon);
891
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
892
    MDBGLOG("rdpfs","sent.");
893
894
    MDBGLOG("rdpfs"," Entering wait loop...");
895
    get_cv_fs(reqid,&lcv,g_fs);
896
    TC_COND_WAIT(lcv,lmutex);
897
    MDBGLOG("rdpfs"," Finished.");
898
899
    if (lfi != NULL && lfi->fh > 0) {
900
      rdpfs_release(path,lfi);
901
    }
902
903
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
904
    if (retstat < 0) {
905
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
906
      MDBGLOG("rdpfs","ERROR [rdpfs_unlink()]: \"%s\" (cbdata->IoStatus.Value = 0x%8.8x; retstat = %d)",nterr,cbdata->IoStatus.Value,retstat);
907
      //g_free(nterr);
908
    }
909
910
    g_memset(cbdata,0,sizeof(callback));
911
912
    TC_MUTEX_UNLOCK(lmutex);
913
    free_reqid_fs(reqid);
914
915
    return retstat;
916
}
917
918
/** Remove a directory */
919
int rdpfs_rmdir(const char *path) {
920
    RDPFS_DECS;
921
    //tbus fd = -1;
922
    int retstat = 0;
923
    char fpath[PATH_MAX];
924
    struct stream * s = NULL;
925
    //struct stat st;
926
    //ptrdiff_t idx = 0;
927
    //tbus objs[1] = { 0x00000000 };
928
    //size_t num_objs = 0;
929
    ptrdiff_t fsize = 0;
930
    struct trans * pcon = (struct trans *)NULL;
931
    int rdpfs_opcode = 0x00000000;
932
    int reqid = -1;
933
    tbus fhandle = 0;
934
    int uniqid = 0;
935
    //tbus empty_fi = 0;
936
    uint32_t pflags = 0x00000000;
937
    uint32_t pshare = 0x00000000;
938
    uint32_t poptions = 0x00000000;
939
    uint32_t pattributes = 0x00000000;
940
    uint32_t crc32 = 0;
941
    const uint32_t magic = RDP_PACKET_MAGIC;
942
    tc_p lmutex = (tc_p)NULL;
943
    tc_p lcv = (tc_p)NULL;
944
    callback * cbdata = NULL;
945
    struct fuse_file_info tfi;
946
    struct fuse_file_info * lfi = &tfi;
947
948
    TC_MUTEX_LOCK(mutex_fsop);
949
    get_reqid_fs(&reqid);
950
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
951
    TC_MUTEX_LOCK(lmutex);
952
    TC_MUTEX_UNLOCK(mutex_fsop);
953
954
    MDBGLOG("rdpfs","\nrdpfs_rmdir(path=\"%s\")\n", path);
955
956
    g_memset(&tfi,0,sizeof(struct fuse_file_info));
957
958
    rdpfs_fullpath(fpath,path);
959
    rdpfs_opcode = RDPFS_RMDIR;
960
    fsize = g_strlen(fpath) + 1;
961
    uniqid = reqid;
962
    cbdata = &(g_reqids[reqid]);
963
964
    pflags |= DELETE;
965
    pshare |= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
966
    poptions |= FILE_DELETE_ON_CLOSE;
967
    retstat = rdpfs_open_args(fpath,lfi,pflags,pshare,poptions,pattributes);
968
    if (retstat < 0) {
969
      MDBGLOG("rdpfs","ERROR [rdpfs_rmdir()]: rdpfs_open_args() returned \"%d\"",retstat);
970
      goto end;
971
    }
972
    fhandle = lfi->fh;
973
    if (fhandle < 1) {
974
      retstat = -EBADF;
975
      MDBGLOG("rdpfs","ERROR [rdpfs_rmdir()]: bad file handle");
976
      goto end;
977
    }
978
979
    if (fsize > 0 && fpath != NULL) {
980
      crc32 = Crc32_ComputeBuf(0, fpath, fsize);
981
    }
982
983
    TC_MUTEX_LOCK(mutex_pcon_fs);
984
    pcon = g_fs->ccon;
985
    pcon->callback_data = cbdata;
986
    s = trans_get_out_s(pcon, MAX_STREAM);
987
    out_uint32_le(s, magic);
988
    out_uint32_le(s, rdpfs_opcode);
989
    out_uint32_le(s, fsize);
990
    out_uint32_le(s, device_id);
991
    out_uint32_le(s, fhandle);
992
    out_uint32_le(s, uniqid);
993
    out_uint32_le(s, crc32);
994
    if (fsize > 0) {
995
      out_uint8a(s, fpath, fsize);
996
    }
997
    s_mark_end(s);
998
    MDBGLOG("rdpfs"," ** rdpfs_rmdir (about to send! fsize = %d; fpath = %s)", fsize, fpath);
999
    fsize = s->end - s->data;
1000
    trans_force_write(pcon);
1001
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
1002
    MDBGLOG("rdpfs","sent.");
1003
1004
    MDBGLOG("rdpfs"," Entering wait loop...");
1005
    get_cv_fs(reqid,&lcv,g_fs);
1006
    TC_COND_WAIT(lcv,lmutex);
1007
    MDBGLOG("rdpfs"," Finished.");
1008
1009
    if (lfi != NULL && lfi->fh > 0) {
1010
      rdpfs_release(path,lfi);
1011
    }
1012
1013
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
1014
    if (retstat < 0) {
1015
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
1016
      MDBGLOG("rdpfs","ERROR [rdpfs_rmdir()]: \"%s\" (cbdata->IoStatus.Value = 0x%8.8x; retstat = %d)",nterr,cbdata->IoStatus.Value,retstat);
1017
      //g_free(nterr);
1018
    }
1019
1020
  end:
1021
    g_memset(cbdata,0,sizeof(callback));
1022
1023
    TC_MUTEX_UNLOCK(lmutex);
1024
    free_reqid_fs(reqid);
1025
1026
    return retstat;
1027
}
1028
1029
/** Create a symbolic link **/
1030
int rdpfs_symlink(const char * ipath, const char * ilink) {
1031
    RDPFS_DECS;
1032
    int retstat = 0;
1033
    int tres = 0;
1034
    char fpath[PATH_MAX] = "";
1035
    //tbus fhandle = 0;
1036
    //int uniqid = 0;
1037
    mode_t mode = 0;
1038
    off_t toffset = 0;
1039
    size_t tsize = 0;
1040
    //ptrdiff_t wv = 0;
1041
    struct fuse_file_info lfi;
1042
    struct fuse_file_info * fi = &lfi;
1043
    MINSHALL_FRENCH_SYMLINK lsl;
1044
    MINSHALL_FRENCH_SYMLINK * sl = &lsl;
1045
    char * path = (char *)NULL;
1046
    char * link = (char *)NULL;
1047
    uint32_t pflags = 0x00000000;
1048
    uint32_t pshare = 0x00000000;
1049
    uint32_t poptions = 0x00000000;
1050
    uint32_t pattributes = 0x00000000;
1051
    LOCAL_STREAM(qs);
1052
1053
    path = (char *)g_strdup(ipath);
1054
    link = (char *)g_strdup(ilink);
1055
1056
    MDBGLOG("rdpfs","\nrdpfs_symlink(path=\"%s\", link=\"%s\")\n", path, link);
1057
1058
    if (path == NULL || link == NULL || g_strlen(path) < 1 || g_strlen(link) < 1) {
1059
      retstat = -EINVAL;
1060
      MDBGLOG("rdpfs","ERROR [rdpfs_symlink()]: either one or both of input arguments PATH or LINK is an empty string or a null pointer");
1061
      goto end_tag;
1062
    }
1063
1064
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
1065
    g_memset(fi,0,sizeof(struct fuse_file_info));
1066
    g_memset(sl,0,sizeof(MINSHALL_FRENCH_SYMLINK));
1067
1068
    construct_MINSHALL_FRENCH_SYMLINK(sl);
1069
    set_MINSHALL_FRENCH_SYMLINK(sl,path);
1070
    send_MINSHALL_FRENCH_SYMLINK(sl,qs);
1071
    s_mark_end(qs);
1072
    tsize = qs->end - qs->data;
1073
1074
    pflags |= FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES;
1075
    pshare |= (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
1076
    poptions |= FILE_NON_DIRECTORY_FILE;
1077
    pattributes |= FILE_ATTRIBUTE_SYSTEM;
1078
1079
    tres = rdpfs_create_args(link,mode,fi,pflags,pshare,poptions,pattributes);
1080
    if (fi == NULL || fi->fh < 1) {
1081
      retstat = -ENOENT;
1082
      goto end_tag;
1083
    }
1084
    if (tres < 0) {
1085
      MDBGLOG("rdpfs","ERROR [rdpfs_symlink()]: rdpfs_create_args() returned code \"%d\"",tres);
1086
      retstat = tres;
1087
      goto rel_tag;
1088
    }
1089
1090
    toffset = 0;
1091
1092
    tres = rdpfs_write(link, (const char *)(qs->data), tsize, toffset, fi);
1093
    if (tres < 0) {
1094
      MDBGLOG("rdpfs","ERROR [rdpfs_symlink()]: rdpfs_write() returned code \"%d\"",retstat);
1095
      retstat = tres;
1096
    }
1097
1098
  rel_tag:
1099
    rdpfs_release(link,fi);
1100
1101
  end_tag:
1102
    if (path != NULL) {
1103
      g_free(path);
1104
    }
1105
    if (link != NULL) {
1106
      g_free(link);
1107
    }
1108
    return retstat;
1109
}
1110
1111
/** Rename a file **/
1112
int rdpfs_rename(const char * path, const char * newpath) {
1113
    RDPFS_DECS;
1114
    //tbus fd = -1;
1115
    int retstat = 0;
1116
    char fpath[PATH_MAX];
1117
    ptrdiff_t fsize = 0;
1118
    char npath[PATH_MAX];
1119
    ptrdiff_t nsize = 0;
1120
    struct stream * s = NULL;
1121
    //struct stat st;
1122
    //ptrdiff_t idx = 0;
1123
    struct trans * pcon = (struct trans *)NULL;
1124
    int rdpfs_opcode = 0x00000000;
1125
    int reqid = -1;
1126
    tbus fhandle = 0;
1127
    int uniqid = 0;
1128
    int ostat = 0;
1129
    size_t cnt = 0;
1130
    tc_p lmutex = (tc_p)NULL;
1131
    tc_p lcv = (tc_p)NULL;
1132
    callback * cbdata = NULL;
1133
    uint32_t pflags = 0;
1134
    uint32_t pshare = 0;
1135
    uint32_t poptions = 0;
1136
    uint32_t pattributes = 0;
1137
    uint32_t crc32 = 0;
1138
    const uint32_t magic = RDP_PACKET_MAGIC;
1139
    struct fuse_file_info tfi;
1140
    struct fuse_file_info * lfi = &tfi;
1141
1142
    MDBGLOG("rdpfs","\nrdpfs_rename(path=\"%s\", newpath=\"%s\")\n", path, newpath);
1143
1144
    TC_MUTEX_LOCK(mutex_fsop);
1145
    get_reqid_fs(&reqid);
1146
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
1147
    TC_MUTEX_LOCK(lmutex);
1148
    TC_MUTEX_UNLOCK(mutex_fsop);
1149
1150
    g_memset(&tfi,0,sizeof(struct fuse_file_info));
1151
1152
    cbdata = &(g_reqids[reqid]);
1153
1154
    lfi->flags |= O_RDWR;
1155
    pflags |= DELETE;
1156
    ostat = rdpfs_open_args(path,lfi,pflags,pshare,poptions,pattributes);
1157
    while (ostat < 0 && cnt < 5) {
1158
      g_sleep(1100);
1159
      ostat = rdpfs_open_args(path,lfi,pflags,pshare,poptions,pattributes);
1160
      cnt++;
1161
    }
1162
    fhandle = lfi->fh;
1163
    if (fhandle < 1) {
1164
      retstat = -ENOENT;
1165
      MDBGLOG("rdpfs","ERROR [rdpfs_rename()]: bad file handle");
1166
      goto end;
1167
    }
1168
1169
    rdpfs_opcode = RDPFS_RENAME;
1170
    uniqid = reqid;
1171
    rdpfs_fullpath(fpath,path);
1172
    fsize = g_strlen(fpath) + 1;
1173
    rdpfs_fullpath(npath,newpath);
1174
    nsize = g_strlen(npath) + 1;
1175
1176
    if (nsize > 0 && npath != NULL) {
1177
      crc32 = Crc32_ComputeBuf(0, npath, nsize);
1178
    }
1179
1180
    TC_MUTEX_LOCK(mutex_pcon_fs);
1181
    pcon = g_fs->ccon;
1182
    pcon->callback_data = cbdata;
1183
    s = trans_get_out_s(pcon, MAX_STREAM);
1184
    out_uint32_le(s, magic);
1185
    out_uint32_le(s, rdpfs_opcode);
1186
    out_uint32_le(s, nsize);
1187
    out_uint32_le(s, device_id);
1188
    out_uint32_le(s, fhandle);
1189
    out_uint32_le(s, uniqid);
1190
    out_uint32_le(s, crc32);
1191
    if (fsize > 0) {
1192
      out_uint8a(s, npath, nsize);
1193
    }
1194
    s_mark_end(s);
1195
    MDBGLOG("rdpfs"," ** rdpfs_rename (about to send! nsize = %d; npath = %s; pdu size = %d)", nsize, npath, (s->end - s->data));
1196
    fsize = s->end - s->data;
1197
    trans_force_write(pcon);
1198
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
1199
    MDBGLOG("rdpfs","sent.");
1200
1201
    MDBGLOG("rdpfs"," Entering wait loop...");
1202
    get_cv_fs(reqid,&lcv,g_fs);
1203
    TC_COND_WAIT(lcv,lmutex);
1204
    MDBGLOG("rdpfs"," Finished.");
1205
1206
    if (lfi != NULL && fhandle > 0) {
1207
      rdpfs_release(path,lfi);
1208
    }
1209
1210
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
1211
    if (retstat < 0) {
1212
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
1213
      MDBGLOG("rdpfs","ERROR [rdpfs_rename()]: \"%s\" (cbdata->IoStatus.Value = 0x%8.8x; retstat = %d)",nterr,cbdata->IoStatus.Value, retstat);
1214
      //g_free(nterr);
1215
    }
1216
    g_memset(cbdata,0,sizeof(callback));
1217
1218
  end:
1219
    TC_MUTEX_UNLOCK(lmutex);
1220
    free_reqid_fs(reqid);
1221
1222
    return retstat;
1223
}
1224
1225
/** Create a hard link to a file */
1226
int rdpfs_link(const char * path, const char * newpath) {
1227
    RDPFS_DECS;
1228
    int retstat = 0;
1229
    MDBGLOG("rdpfs","\nrdpfs_link(path=\"%s\", newpath=\"%s\")\n", path, newpath);
1230
    retstat = -EOPNOTSUPP;
1231
    return retstat;
1232
}
1233
1234
/** Change the permission bits of a file */
1235
int rdpfs_chmod(const char *path, mode_t mode) {
1236
    RDPFS_DECS;
1237
    int retstat = 0;
1238
    MDBGLOG("rdpfs","\nrdpfs_chmod(path=\"%s\", mode=0%03o)\n", path, mode);
1239
    return retstat;
1240
}
1241
1242
/** Change the owner and group of a file */
1243
int rdpfs_chown(const char *path, uid_t uid, gid_t gid) {
1244
    RDPFS_DECS;
1245
    int retstat = 0;
1246
    MDBGLOG("rdpfs","\nrdpfs_chown(path=\"%s\", uid=%d, gid=%d)\n", path, uid, gid);
1247
    return retstat;
1248
}
1249
1250
/** Change the size of a file */
1251
int rdpfs_truncate(const char * path, off_t newsize) {
1252
    RDPFS_DECS;
1253
    int retstat = 0;
1254
    struct fuse_file_info * lfi = NULL;
1255
    uint32_t pflags = 0x00000000;
1256
    uint32_t pshare = 0x00000000;
1257
    uint32_t poptions = 0x00000000;
1258
    uint32_t pattributes = 0x00000000;
1259
1260
    MDBGLOG("rdpfs","\nrdpfs_truncate(path=\"%s\", newsize=%lld)\n", path, newsize);
1261
1262
    lfi = (struct fuse_file_info *)g_malloc(sizeof(struct fuse_file_info), 1);
1263
    lfi->flags = O_WRONLY;
1264
    pflags |= FILE_WRITE_DATA;
1265
1266
    retstat = rdpfs_open_args(path, lfi, pflags, pshare, poptions, pattributes);
1267
    if (retstat < 0) {
1268
      goto end;
1269
    }
1270
    retstat = rdpfs_ftruncate(path, newsize, lfi);
1271
    rdpfs_release(path, lfi);
1272
1273
  end:
1274
    if (lfi != NULL) {
1275
      g_free(lfi);
1276
    }
1277
1278
    return retstat;
1279
}
1280
1281
/** Change the access and/or modification times of a file */
1282
/* note -- I'll want to change this as soon as 2.6 is in debian testing */
1283
int rdpfs_utime(const char * path, struct utimbuf * ubuf) {
1284
    RDPFS_DECS;
1285
    int retstat = 0;
1286
    //tbus fd = -1;
1287
    char fpath[PATH_MAX] = "";
1288
    struct stream * s = NULL;
1289
    //struct stat st;
1290
    //ptrdiff_t idx = 0;
1291
    //tbus objs[1] = { 0x00000000 };
1292
    //size_t num_objs = 0;
1293
    ptrdiff_t fsize = 0;
1294
    struct trans * pcon = (struct trans *)NULL;
1295
    int rdpfs_opcode = 0x00000000;
1296
    int reqid = -1;
1297
    tbus fhandle = 0;
1298
    int uniqid = 0;
1299
    //tbus empty_fi = 0;
1300
    int ostat = 0;
1301
    size_t cnt = 0;
1302
    struct fuse_file_info * lfi = NULL;
1303
    tc_p lmutex = (tc_p)NULL;
1304
    tc_p lcv = (tc_p)NULL;
1305
    callback * cbdata = NULL;
1306
    uint64_t actime = 0x0000000000000000;
1307
    uint64_t modtime = 0x0000000000000000;
1308
    //uint64_t creationtime = 0x0000000000000000;
1309
    //uint64_t changetime = 0x0000000000000000;
1310
    //uint32_t fileattributes = 0x00000000;
1311
    //uint32_t reserved = 0x00000000;
1312
    struct stat statbuf;
1313
    struct stat * sb = &statbuf;
1314
    uint32_t * p_crc32 = (uint32_t *)NULL;
1315
    uint32_t crc32 = 0;
1316
    const uint32_t magic = RDP_PACKET_MAGIC;
1317
    char * p = (char *)NULL;
1318
1319
    g_memset(sb,0,sizeof(struct stat));
1320
1321
    TC_MUTEX_LOCK(mutex_fsop);
1322
    get_reqid_fs(&reqid);
1323
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
1324
    TC_MUTEX_LOCK(lmutex);
1325
    TC_MUTEX_UNLOCK(mutex_fsop);
1326
1327
    MDBGLOG("rdpfs","\nrdpfs_utime(path=\"%s\")\n", path);
1328
1329
    cbdata = &(g_reqids[reqid]);
1330
1331
    lfi = (struct fuse_file_info *)g_malloc(sizeof(struct fuse_file_info), 1);
1332
    lfi->flags |= O_RDWR;
1333
    ostat = rdpfs_open(path,lfi);
1334
    while (ostat < 0 && cnt < 5) {
1335
      g_sleep(1100);
1336
      ostat = rdpfs_open(path,lfi);
1337
      cnt++;
1338
    }
1339
    fhandle = lfi->fh;
1340
    if (fhandle < 1) {
1341
      goto end;
1342
    }
1343
    rdpfs_fgetattr(path,sb,lfi);
1344
    actime = UnixToFileTime(ubuf->actime);
1345
    modtime = UnixToFileTime(ubuf->modtime);
1346
1347
    rdpfs_fullpath(fpath,path);
1348
    rdpfs_opcode = RDPFS_UTIME;
1349
    fsize = g_strlen(fpath) + 1;
1350
    uniqid = reqid;
1351
1352
    TC_MUTEX_LOCK(mutex_pcon_fs);
1353
    pcon = g_fs->ccon;
1354
    pcon->callback_data = cbdata;
1355
    s = trans_get_out_s(pcon, MAX_STREAM);
1356
    out_uint32_le(s, magic);
1357
    out_uint32_le(s, rdpfs_opcode);
1358
    out_uint32_le(s, fsize + 16);
1359
    out_uint32_le(s, device_id);
1360
    out_uint32_le(s, fhandle);
1361
    out_uint32_le(s, uniqid);
1362
    p_crc32 = (uint32_t *)s_get_pos(s);
1363
    out_uint32_le(s, crc32);
1364
    p = (char *)s_get_pos(s);
1365
    out_uint64_le(s, actime);
1366
    out_uint64_le(s, modtime);
1367
    if (fsize > 0) {
1368
      out_uint8a(s, fpath, fsize);
1369
    }
1370
    s_mark_end(s);
1371
1372
    if (p_crc32 != NULL) {
1373
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
1374
    }
1375
1376
    MDBGLOG("rdpfs"," ** rdpfs_utime (about to send! fsize = %d; fpath = %s)", fsize, fpath);
1377
    fsize = s->end - s->data;
1378
    trans_force_write(pcon);
1379
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
1380
    MDBGLOG("rdpfs","sent.");
1381
1382
    MDBGLOG("rdpfs"," Entering wait loop...");
1383
    get_cv_fs(reqid,&lcv,g_fs);
1384
    TC_COND_WAIT(lcv,lmutex);
1385
    MDBGLOG("rdpfs"," Finished.");
1386
1387
    if (lfi != NULL && fhandle > 0) {
1388
      rdpfs_release(path,lfi);
1389
    }
1390
1391
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
1392
    if (retstat < 0) {
1393
      MDBGLOG("rdpfs","ERROR [rdpfs_utime()]: cbdata->IoStatus.Value = 0x%8.8x; retstat = %d",cbdata->IoStatus.Value, retstat);
1394
    }
1395
    g_memset(cbdata,0,sizeof(callback));
1396
1397
  end:
1398
    TC_MUTEX_UNLOCK(lmutex);
1399
    free_reqid_fs(reqid);
1400
    if (lfi != NULL) {
1401
      g_free(lfi);
1402
    }
1403
1404
    return retstat;
1405
}
1406
1407
/** File open operation
1408
 *
1409
 * No creation, or truncation flags (O_CREAT, O_EXCL, O_TRUNC)
1410
 * will be passed to open().  Open should check if the operation
1411
 * is permitted for the given flags.  Optionally open may also
1412
 * return an arbitrary filehandle in the fuse_file_info structure,
1413
 * which will be passed to all file operations.
1414
 *
1415
 * Changed in version 2.2
1416
 */
1417
int rdpfs_open(const char * path, struct fuse_file_info * fi) {
1418
    RDPFS_DECS;
1419
    int retstat = 0;
1420
    //tbus fd = -1;
1421
    char fpath[PATH_MAX];
1422
    struct stream * s = NULL;
1423
    char buf[512];
1424
    struct stat st;
1425
    //ptrdiff_t idx = 0;
1426
    //tbus objs[1] = { 0x00000000 };
1427
    //size_t num_objs = 0;
1428
    //int timeout = 0;
1429
    struct trans * pcon = (struct trans *)NULL;
1430
    int rdpfs_opcode = 0x00000000;
1431
    ptrdiff_t size = 0x00000000;
1432
    struct _rdpfs_data rdata;
1433
    tc_p lmutex = (tc_p)NULL;
1434
    tc_p lcv = (tc_p)NULL;
1435
    callback * cbdata = NULL;
1436
    uint32_t pflags = 0x00000000;
1437
    uint32_t pshare = 0x00000000;
1438
    uint32_t poptions = 0x00000000;
1439
    uint32_t pattributes = 0x00000000;
1440
    uint32_t crc32 = 0;
1441
    uint32_t * p_crc32 = (uint32_t *)NULL;
1442
    const uint32_t magic = RDP_PACKET_MAGIC;
1443
    char * p = (char *)NULL;
1444
    int reqid = -1;
1445
    tbus fhandle = 0;
1446
    int uniqid = 0;
1447
    struct stat lstatbuf;
1448
    struct stat * statbuf = &lstatbuf;
1449
1450
    MDBGLOG("rdpfs","\n\nrdpfs_open(path=\"%s\")\n",path);
1451
1452
    g_memset(&st,0,sizeof(struct stat));
1453
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
1454
    g_memset(buf,0,sizeof(char)*512);
1455
    g_memset(&rdata,0,sizeof(rdpfs_data));
1456
    g_memset(statbuf,0,sizeof(struct stat));
1457
1458
    rdpfs_fullpath(fpath, path);
1459
1460
    TC_MUTEX_LOCK(mutex_fsop);
1461
    get_reqid_fs(&reqid);
1462
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
1463
    TC_MUTEX_LOCK(lmutex);
1464
    TC_MUTEX_UNLOCK(mutex_fsop);
1465
1466
    get_cv_fs(reqid, &lcv,g_fs);
1467
    cbdata = &(g_reqids[reqid]);
1468
1469
    if ((fi->flags & O_ACCMODE) == O_RDONLY) {
1470
	pflags |= FILE_READ_DATA;
1471
    }
1472
    else if ((fi->flags & O_ACCMODE) == O_WRONLY) {
1473
	pflags |= FILE_WRITE_DATA;
1474
    }
1475
    else if ((fi->flags & O_ACCMODE) == O_RDWR) {
1476
	pflags |= (FILE_READ_DATA | FILE_WRITE_DATA);
1477
    }
1478
    else {
1479
      //pflags |= MAXIMUM_ALLOWED;
1480
      pflags = GENERIC_ALL;
1481
    }
1482
1483
    pshare |= (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
1484
1485
    rdpfs_opcode = RDPFS_OPEN;
1486
    size = g_strlen(fpath) + 1;
1487
    uniqid = reqid;
1488
1489
    TC_MUTEX_LOCK(mutex_pcon_fs);
1490
    pcon = g_fs->ccon;
1491
    pcon->callback_data = cbdata;
1492
    s = trans_get_out_s(pcon, MAX_STREAM);
1493
    out_uint32_le(s, magic);
1494
    out_uint32_le(s, rdpfs_opcode);
1495
    out_uint32_le(s, size + 16);
1496
    out_uint32_le(s, device_id);
1497
    out_uint32_le(s, fhandle);
1498
    out_uint32_le(s, uniqid);
1499
    p_crc32 = (uint32_t *)s_get_pos(s);
1500
    out_uint32_le(s, crc32);
1501
    p = (char *)s_get_pos(s);
1502
    out_uint32_le(s, pflags);
1503
    out_uint32_le(s, pshare);
1504
    out_uint32_le(s, poptions);
1505
    out_uint32_le(s, pattributes);
1506
    if (size > 0) {
1507
      out_uint8a(s, fpath, size);
1508
    }
1509
    s_mark_end(s);
1510
    size = s->end - s->data;
1511
    if (p_crc32 != NULL) {
1512
      *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1513
    }
1514
1515
    MDBGLOG("rdpfs"," ** rdpfs_open(): sending [g_fd = %d]", g_fd);
1516
    trans_force_write(pcon);
1517
    g_memset(s->data,0,MAX_STREAM);
1518
    MDBGLOG("rdpfs","sent.");
1519
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
1520
1521
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
1522
    TC_COND_WAIT(lcv, lmutex);
1523
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
1524
1525
    fhandle = cbdata->FileId;
1526
1527
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
1528
    if (retstat < 0) {
1529
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
1530
      MDBGLOG("rdpfs","ERROR [rdpfs_open()]: \"%s\" (retstat = %d; cbdata->IoStatus.Fields.Sev = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
1531
      fhandle = -1;
1532
    }
1533
    fi->fh = fhandle;
1534
    //log_fi(fi);
1535
1536
    MDBGLOG("rdpfs","rdpfs_open(): done. (fi->fh = %d; fhandle = %d; retstat = %d)",fi->fh,fhandle,retstat);
1537
1538
    TC_MUTEX_UNLOCK(lmutex);
1539
    free_reqid_fs(reqid);
1540
1541
    return retstat;
1542
}
1543
1544
int rdpfs_open_args(const char * path, struct fuse_file_info * fi, uint32_t pflags, uint32_t pshare, uint32_t poptions, uint32_t pattributes) {
1545
    RDPFS_DECS;
1546
    int retstat = 0;
1547
    //tbus fd = -1;
1548
    char fpath[PATH_MAX];
1549
    struct stream * s = NULL;
1550
    char buf[512];
1551
    struct stat st;
1552
    //ptrdiff_t idx = 0;
1553
    //tbus objs[1] = { 0x00000000 };
1554
    //size_t num_objs = 0;
1555
    //int timeout = 0;
1556
    struct trans * pcon = (struct trans *)NULL;
1557
    int rdpfs_opcode = 0x00000000;
1558
    ptrdiff_t size = 0x00000000;
1559
    struct _rdpfs_data rdata;
1560
    tc_p lmutex = (tc_p)NULL;
1561
    tc_p lcv = (tc_p)NULL;
1562
    callback * cbdata = NULL;
1563
    int reqid = -1;
1564
    tbus fhandle = 0;
1565
    int uniqid = 0;
1566
    struct stat lstatbuf;
1567
    struct stat * statbuf = &lstatbuf;
1568
    uint32_t crc32 = 0;
1569
    uint32_t * p_crc32 = (uint32_t *)NULL;
1570
    const uint32_t magic = RDP_PACKET_MAGIC;
1571
    char * p = (char *)NULL;
1572
1573
    MDBGLOG("rdpfs","\n\nrdpfs_open_args(path = \"%s\"; pflags = 0x%8.8x; pshare  = 0x%8.8x; poptions = 0x%8.8x)\n",path,pflags,pshare,poptions);
1574
1575
    g_memset(&st,0,sizeof(struct stat));
1576
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
1577
    g_memset(buf,0,sizeof(char)*512);
1578
    g_memset(&rdata,0,sizeof(rdpfs_data));
1579
    g_memset(statbuf,0,sizeof(struct stat));
1580
1581
    rdpfs_fullpath(fpath, path);
1582
1583
    TC_MUTEX_LOCK(mutex_fsop);
1584
    get_reqid_fs(&reqid);
1585
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
1586
    TC_MUTEX_LOCK(lmutex);
1587
    TC_MUTEX_UNLOCK(mutex_fsop);
1588
1589
    get_cv_fs(reqid, &lcv,g_fs);
1590
    cbdata = &(g_reqids[reqid]);
1591
1592
    rdpfs_opcode = RDPFS_OPEN;
1593
    size = g_strlen(fpath) + 1;
1594
    uniqid = reqid;
1595
1596
    TC_MUTEX_LOCK(mutex_pcon_fs);
1597
    pcon = g_fs->ccon;
1598
    pcon->callback_data = cbdata;
1599
    s = trans_get_out_s(pcon, MAX_STREAM);
1600
    out_uint32_le(s, magic);
1601
    out_uint32_le(s, rdpfs_opcode);
1602
    out_uint32_le(s, size + 16);
1603
    out_uint32_le(s, device_id);
1604
    out_uint32_le(s, fhandle);
1605
    out_uint32_le(s, uniqid);
1606
    p_crc32 = (uint32_t *)s_get_pos(s);
1607
    out_uint32_le(s, crc32);
1608
    p = (char *)s_get_pos(s);
1609
    out_uint32_le(s, pflags);
1610
    out_uint32_le(s, pshare);
1611
    out_uint32_le(s, poptions);
1612
    out_uint32_le(s, pattributes);
1613
    if (size > 0) {
1614
      out_uint8a(s, fpath, size);
1615
    }
1616
    s_mark_end(s);
1617
    size = s->end - s->data;
1618
    if (p_crc32 != NULL) {
1619
      *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1620
    }
1621
1622
    MDBGLOG("rdpfs"," ** rdpfs_open_args(): sending [g_fd = %d]", g_fd);
1623
    trans_force_write(pcon);
1624
    g_memset(s->data,0,MAX_STREAM);
1625
    MDBGLOG("rdpfs","sent.");
1626
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
1627
1628
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
1629
    TC_COND_WAIT(lcv, lmutex);
1630
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
1631
1632
    fhandle = cbdata->FileId;
1633
1634
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
1635
    if (retstat < 0) {
1636
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
1637
      MDBGLOG("rdpfs","ERROR [rdpfs_open_args()]: \"%s\" (retstat = %d; cbdata->IoStatus.Fields.Sev = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
1638
      fhandle = -1;
1639
    }
1640
    fi->fh = fhandle;
1641
    //log_fi(fi);
1642
1643
    MDBGLOG("rdpfs","rdpfs_open_args(): done. (fi->fh = %d; fhandle = %d; retstat = %d)",fi->fh,fhandle,retstat);
1644
1645
    TC_MUTEX_UNLOCK(lmutex);
1646
    free_reqid_fs(reqid);
1647
1648
    return retstat;
1649
}
1650
1651
/** Read data from an open file
1652
 *
1653
 * Read should return exactly the number of bytes requested except
1654
 * on EOF or error, otherwise the rest of the data will be
1655
 * substituted with zeroes.  An exception to this is when the
1656
 * 'direct_io' mount option is specified, in which case the return
1657
 * value of the read system call will reflect the return value of
1658
 * this operation.
1659
 *
1660
 * Changed in version 2.2
1661
 */
1662
// I don't fully understand the documentation above -- it doesn't
1663
// match the documentation for the read() system call which says it
1664
// can return with anything up to the amount of data requested. nor
1665
// with the fusexmp code which returns the amount of data also
1666
// returned by read.
1667
1668
static int APP_CC rdpfs_read_chunk(const char * path, char * buf, size_t size, off_t offset, struct fuse_file_info * fi) {
1669
    RDPFS_DECS;
1670
    int retstat = 0;
1671
    //tbus fd = -1;
1672
    ptrdiff_t plen = 0;
1673
    char fpath[PATH_MAX];
1674
    struct stream * s = NULL;
1675
    //struct stat st;
1676
    //ptrdiff_t idx = 0;
1677
    //tbus objs[1] = { 0x00000000 };
1678
    //size_t num_objs = 0;
1679
    ptrdiff_t fsize = 0;
1680
    struct trans * pcon = (struct trans *)NULL;
1681
    int rdpfs_opcode = 0x00000000;
1682
    int reqid = -1;
1683
    tbus fhandle = 0;
1684
    int uniqid = 0;
1685
    //tbus empty_fi = 0;
1686
    struct fuse_file_info * lfi = NULL;
1687
    tc_p lmutex = (tc_p)NULL;
1688
    tc_p lcv = (tc_p)NULL;
1689
    callback * cbdata = NULL;
1690
    int mode = 0;
1691
    struct stat lstatbuf;
1692
    struct stat * statbuf = &lstatbuf;
1693
    uint32_t crc32 = 0;
1694
    uint32_t * p_crc32 = (uint32_t *)NULL;
1695
    const uint32_t magic = RDP_PACKET_MAGIC;
1696
    char * p = (char *)NULL;
1697
1698
    TC_MUTEX_LOCK(mutex_fsop);
1699
    get_reqid_fs(&reqid);
1700
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
1701
    TC_MUTEX_LOCK(lmutex);
1702
    TC_MUTEX_UNLOCK(mutex_fsop);
1703
1704
    plen = g_strlen(path);
1705
    if (path != NULL && plen > 0) {
1706
      g_strncpy(fpath,path,MIN(PATH_MAX - 1,plen));
1707
    }
1708
1709
    lfi = fi;
1710
    fhandle = lfi->fh;
1711
    mode = lfi->flags & O_ACCMODE;
1712
1713
    MDBGLOG("rdpfs","\nINFO\t[%s()]: called (path=\"%s\", buf=0x%8.8x, size=%d, offset=%llu, fi=0x%8.8x, lfi=0x%8.8x, statbuf->st_size = %d, mode = 0x%8.8x, O_RDONLY = %d, O_RDWR = %d, O_WRONLY = %d)\n",
1714
	 __func__, path, buf, size, offset, fi, lfi, statbuf->st_size,
1715
		mode, (mode & O_RDONLY), (mode & O_RDWR), (mode & O_WRONLY));
1716
1717
    cbdata = &(g_reqids[reqid]);
1718
    cbdata->userdata = (unsigned char *)buf;
1719
    if (g_fs != NULL) {
1720
      device_id = g_fs->device_id;
1721
      cbdata->fs = g_fs;
1722
    }
1723
    cbdata->device_id = device_id;
1724
1725
    rdpfs_opcode = RDPFS_READ;
1726
    fsize = g_strlen(fpath) + 1;
1727
    uniqid = reqid;
1728
1729
    TC_MUTEX_LOCK(mutex_pcon_fs);
1730
    pcon = g_fs->ccon;
1731
    pcon->callback_data = cbdata;
1732
    s = trans_get_out_s(pcon, MAX_STREAM);
1733
    out_uint32_le(s, magic);
1734
    out_uint32_le(s, rdpfs_opcode);
1735
    out_uint32_le(s, fsize + 12);
1736
    out_uint32_le(s, device_id);
1737
    out_uint32_le(s, fhandle);
1738
    out_uint32_le(s, uniqid);
1739
    p_crc32 = (uint32_t *)s_get_pos(s);
1740
    out_uint32_le(s, crc32);
1741
    p = (char *)s_get_pos(s);
1742
    out_uint32_le(s, size);
1743
    out_uint64_le(s, offset);
1744
    if (fsize > 0) {
1745
      out_uint8a(s, fpath, fsize);
1746
    }
1747
    s_mark_end(s);
1748
    if (p_crc32 != NULL) {
1749
      *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1750
    }
1751
    MDBGLOG("rdpfs"," ** rdpfs_read_chunk (about to send! size = %d; fsize = %d; offset = %lu; fpath = %s)", size, fsize, offset, fpath);
1752
    fsize = s->end - s->data;
1753
    trans_force_write(pcon);
1754
    g_memset(s->data,0,sizeof(char)*MAX_STREAM);
1755
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
1756
    MDBGLOG("rdpfs","sent.");
1757
1758
    MDBGLOG("rdpfs"," Entering wait loop...");
1759
    get_cv_fs(reqid,&lcv,g_fs);
1760
    TC_COND_WAIT(lcv,lmutex);
1761
    MDBGLOG("rdpfs"," Finished.");
1762
1763
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
1764
    if (retstat < 0) {
1765
      const char * nterr = (const char *)ntstatus_string(cbdata->IoStatus.Value);
1766
      MDBGLOG("rdpfs","ERROR [rdpfs_read_chunk()]: \"%s\" (retstat = %d; cbdata->IoStatus.Value = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
1767
      //retstat = 0;
1768
    }
1769
    else {
1770
      retstat = cbdata->length;
1771
    }
1772
    g_memset(cbdata,0,sizeof(callback));
1773
1774
    TC_MUTEX_UNLOCK(lmutex);
1775
    free_reqid_fs(reqid);
1776
1777
    return retstat;
1778
}
1779
1780
int rdpfs_read(const char * path, char * buf, size_t size, off_t offset, struct fuse_file_info * fi) {
1781
    RDPFS_DECS;
1782
    #ifndef CHUNK_SIZE
1783
    #define CHUNK_SIZE 4096
1784
    #endif
1785
    //tbus fd = -1;
1786
    int retstat = 0;
1787
    char fpath[PATH_MAX];
1788
    //struct stream * s = NULL;
1789
    //struct stat st;
1790
    ptrdiff_t idx = 0;
1791
    //tbus objs[1] = { 0x00000000 };
1792
    //size_t num_objs = 0;
1793
    //ptrdiff_t fsize = 0;
1794
    //struct trans * pcon = (struct trans *)NULL;
1795
    //int rdpfs_opcode = 0x00000000;
1796
    //int reqid = -1;
1797
    tbus fhandle = 0;
1798
    //int uniqid = 0;
1799
    //tbus empty_fi = 0;
1800
    struct fuse_file_info * lfi = NULL;
1801
    //tc_p lmutex = (tc_p)NULL;
1802
    //tc_p lcv = (tc_p)NULL;
1803
    //callback * cbdata = NULL;
1804
    int mode = 0;
1805
    struct stat lstatbuf;
1806
    struct stat * statbuf = &lstatbuf;
1807
    size_t chunks = 0;
1808
    char * tpos = (char *)NULL;
1809
    off_t toffset = 0;
1810
    size_t tsize = 0;
1811
    uint64_t tally = 0;
1812
1813
    g_memset(statbuf,0,sizeof(struct stat));
1814
1815
    lfi = fi;
1816
    fhandle = lfi->fh;
1817
    mode = lfi->flags & O_ACCMODE;
1818
    rdpfs_fgetattr(path,statbuf,lfi);
1819
    rdpfs_fullpath(fpath,path);
1820
1821
    MDBGLOG("rdpfs","\nrdpfs_read(path=\"%s\", buf=0x%8.8x, size=%d, offset=%llu, fi=0x%8.8x, lfi=0x%8.8x, statbuf->st_size = %d, mode = 0x%8.8x, O_RDONLY = %d, O_RDWR = %d, O_WRONLY = %d)\n",
1822
	    path, buf, size, offset, fi, lfi, statbuf->st_size,
1823
		mode, (mode & O_RDONLY), (mode & O_RDWR), (mode & O_WRONLY));
1824
1825
    if (size > statbuf->st_size) {
1826
      size = statbuf->st_size;
1827
    }
1828
1829
    chunks = (size == 0) ? 0 : 1;
1830
    if (size > CHUNK_SIZE) {
1831
      chunks = ((size % CHUNK_SIZE) == 0) ? size / CHUNK_SIZE : (size / CHUNK_SIZE) + 1;
1832
    }
1833
1834
    for (idx = 0; idx < chunks; idx++) {
1835
      tpos = buf + (idx * CHUNK_SIZE);
1836
      toffset = offset + (idx * CHUNK_SIZE);
1837
      tsize = (idx == (chunks - 1) && (size % CHUNK_SIZE) != 0) ? size % CHUNK_SIZE : CHUNK_SIZE;
1838
      retstat = rdpfs_read_chunk(fpath,tpos,tsize,toffset,lfi);
1839
      if (retstat < 0) {
1840
	break;
1841
      }
1842
      else {
1843
	tally += retstat;
1844
      }
1845
    }
1846
    if (retstat > -1) {
1847
      retstat = tally;
1848
    }
1849
1850
    return retstat;
1851
}
1852
1853
/** Write data to an open file
1854
 *
1855
 * Write should return exactly the number of bytes requested
1856
 * except on error.  An exception to this is when the 'direct_io'
1857
 * mount option is specified (see read operation).
1858
 *
1859
 * Changed in version 2.2
1860
 */
1861
static int rdpfs_write_chunk(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
1862
    RDPFS_DECS;
1863
    //tbus fd = -1;
1864
    int retstat = 0;
1865
    char fpath[PATH_MAX];
1866
    struct stream * s = NULL;
1867
    //struct stat st;
1868
    //ptrdiff_t idx = 0;
1869
    //tbus objs[1] = { 0x00000000 };
1870
    //size_t num_objs = 0;
1871
    ptrdiff_t fsize = 0;
1872
    struct trans * pcon = (struct trans *)NULL;
1873
    int rdpfs_opcode = 0x00000000;
1874
    int reqid = -1;
1875
    tbus fhandle = 0;
1876
    int uniqid = 0;
1877
    tbus empty_fi = 0;
1878
    struct fuse_file_info * lfi = NULL;
1879
    tc_p lmutex = (tc_p)NULL;
1880
    tc_p lcv = (tc_p)NULL;
1881
    callback * cbdata = NULL;
1882
    uint32_t crc32 = 0;
1883
    uint32_t * p_crc32 = (uint32_t *)NULL;
1884
    const uint32_t magic = RDP_PACKET_MAGIC;
1885
    char * p = (char *)NULL;
1886
1887
    lfi = fi;
1888
    fhandle = lfi->fh;
1889
1890
    TC_MUTEX_LOCK(mutex_fsop);
1891
    get_reqid_fs(&reqid);
1892
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
1893
    TC_MUTEX_LOCK(lmutex);
1894
    TC_MUTEX_UNLOCK(mutex_fsop);
1895
1896
    MDBGLOG("rdpfs","\nrdpfs_write_chunk(path=\"%s\", buf=0x%8.8x, size=%d, offset=%lld, fi=0x%8.8x)\n",
1897
	    path, buf, size, offset, fi);
1898
1899
    cbdata = &(g_reqids[reqid]);
1900
    cbdata->userdata = (unsigned char *)buf;
1901
1902
    rdpfs_fullpath(fpath,path);
1903
1904
    rdpfs_opcode = RDPFS_WRITE;
1905
    fsize = g_strlen(fpath) + 1;
1906
    uniqid = reqid;
1907
1908
    TC_MUTEX_LOCK(mutex_pcon_fs);
1909
    pcon = g_fs->ccon;
1910
    pcon->callback_data = cbdata;
1911
    s = trans_get_out_s(pcon, MAX_STREAM);
1912
    out_uint32_le(s, magic);
1913
    out_uint32_le(s, rdpfs_opcode);
1914
    out_uint32_le(s, (fsize + size + 12));
1915
    out_uint32_le(s, device_id);
1916
    out_uint32_le(s, fhandle);
1917
    out_uint32_le(s, uniqid);
1918
    p_crc32 = (uint32_t *)s_get_pos(s);
1919
    out_uint32_le(s, crc32);
1920
    p = (char *)s_get_pos(s);
1921
    out_uint32_le(s, size);
1922
    out_uint64_le(s, offset);
1923
    if (fsize > 0) {
1924
      out_uint8a(s, fpath, fsize);
1925
    }
1926
    if (size > 0) {
1927
      out_uint8a(s, buf, size);
1928
    }
1929
    s_mark_end(s);
1930
    if (p_crc32 != NULL) {
1931
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
1932
    }
1933
    MDBGLOG("rdpfs"," ** rdpfs_write_chunk (about to send! size = %d; fsize = %d; offset = %lu; fpath = %s)", size, fsize, offset, fpath);
1934
    fsize = s->end - s->data;
1935
    trans_force_write(pcon);
1936
    g_memset(s->data,0,sizeof(char)*MAX_STREAM);
1937
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
1938
    MDBGLOG("rdpfs","sent.");
1939
1940
    MDBGLOG("rdpfs"," Entering wait loop...");
1941
    get_cv_fs(reqid,&lcv,g_fs);
1942
    TC_COND_WAIT(lcv,lmutex);
1943
    MDBGLOG("rdpfs"," Finished.");
1944
1945
    if (empty_fi > 0 && lfi != NULL) {
1946
      rdpfs_release(path,lfi);
1947
    }
1948
1949
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
1950
    if (retstat < 0) {
1951
      MDBGLOG("rdpfs","ERROR [rdpfs_write_chunk()]: retstat = %d; cbdata->IoStatus.Value = %d",retstat,cbdata->IoStatus.Value);
1952
    }
1953
    else {
1954
      retstat = cbdata->length;
1955
    }
1956
    g_memset(cbdata,0,sizeof(callback));
1957
1958
    TC_MUTEX_UNLOCK(lmutex);
1959
    free_reqid_fs(reqid);
1960
1961
    return retstat;
1962
}
1963
1964
static int rdpfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
1965
    RDPFS_DECS;
1966
    #ifndef CHUNK_SIZE
1967
    #define CHUNK_SIZE 4096
1968
    #endif
1969
    //tbus fd = -1;
1970
    int retstat = 0;
1971
    char fpath[PATH_MAX];
1972
    //struct stream * s = NULL;
1973
    ptrdiff_t idx = 0;
1974
    //ptrdiff_t fsize = 0;
1975
    //struct trans * pcon = (struct trans *)NULL;
1976
    //int rdpfs_opcode = 0x00000000;
1977
    //int reqid = -1;
1978
    tbus fhandle = 0;
1979
    //int uniqid = 0;
1980
    //tbus empty_fi = 0;
1981
    struct fuse_file_info * lfi = NULL;
1982
    //tc_p lmutex = (tc_p)NULL;
1983
    //tc_p lcv = (tc_p)NULL;
1984
    //callback * cbdata = NULL;
1985
    int mode = 0;
1986
    size_t chunks = 0;
1987
    char * tpos = (char *)NULL;
1988
    off_t toffset = 0;
1989
    size_t tsize = 0;
1990
    uint64_t tally = 0;
1991
1992
    lfi = fi;
1993
    fhandle = lfi->fh;
1994
    mode = lfi->flags & O_ACCMODE;
1995
    rdpfs_fullpath(fpath,path);
1996
1997
    MDBGLOG("rdpfs","\nrdpfs_write(path=\"%s\", buf=0x%8.8x, size=%d, offset=%llu, fi=0x%8.8x, lfi=0x%8.8x, mode = 0x%8.8x, O_RDONLY = %d, O_RDWR = %d, O_WRONLY = %d)\n",
1998
	    path, buf, size, offset, fi, lfi,
1999
		mode, (mode & O_RDONLY), (mode & O_RDWR), (mode & O_WRONLY));
2000
2001
    chunks = (size == 0) ? 0 : 1;
2002
    if (size > CHUNK_SIZE) {
2003
      chunks = ((size % CHUNK_SIZE) == 0) ? size / CHUNK_SIZE : (size / CHUNK_SIZE) + 1;
2004
    }
2005
2006
    for (idx = 0; idx < chunks; idx++) {
2007
      tpos = (char *)buf + (idx * CHUNK_SIZE);
2008
      toffset = offset + (idx * CHUNK_SIZE);
2009
      tsize = (idx == (chunks - 1) && (size % CHUNK_SIZE) != 0) ? size % CHUNK_SIZE : CHUNK_SIZE;
2010
      retstat = rdpfs_write_chunk(path,tpos,tsize,toffset,lfi);
2011
      if (retstat < 0) {
2012
	break;
2013
      }
2014
      else {
2015
	tally += retstat;
2016
      }
2017
    }
2018
    if (retstat > -1) {
2019
      retstat = tally;
2020
    }
2021
2022
    return retstat;
2023
}
2024
2025
2026
/** Get file system statistics
2027
 *
2028
 * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
2029
 *
2030
 * Replaced 'struct statfs' parameter with 'struct statvfs' in
2031
 * version 2.5
2032
 */
2033
int rdpfs_statfs(const char *path, struct statvfs *statv) {
2034
    RDPFS_DECS;
2035
    //tbus fd = -1;
2036
    int retstat = 0;
2037
    char fpath[PATH_MAX];
2038
    struct stream * s = NULL;
2039
    //struct stat st;
2040
    //ptrdiff_t idx = 0;
2041
    //tbus objs[1] = { 0x00000000 };
2042
    //size_t num_objs = 0;
2043
    ptrdiff_t fsize = 0;
2044
    struct trans * pcon = (struct trans *)NULL;
2045
    int rdpfs_opcode = 0x00000000;
2046
    int reqid = -1;
2047
    tbus fhandle = 0;
2048
    int uniqid = 0;
2049
    //tbus empty_fi = 0;
2050
    struct fuse_file_info * lfi = NULL;
2051
    tc_p lmutex = (tc_p)NULL;
2052
    tc_p lcv = (tc_p)NULL;
2053
    callback * cbdata = NULL;
2054
    FILE_FS_FULL_SIZE_INFORMATION * vbuf = (FILE_FS_FULL_SIZE_INFORMATION *)NULL;
2055
    int bytes_per_sector = 0;
2056
    int sectors_per_block = 0;
2057
    int bytes_per_block = 0;
2058
    uint32_t crc32 = 0;
2059
    uint32_t * p_crc32 = (uint32_t *)NULL;
2060
    const uint32_t magic = RDP_PACKET_MAGIC;
2061
    char * p = (char *)NULL;
2062
2063
    TC_MUTEX_LOCK(mutex_fsop);
2064
    get_reqid_fs(&reqid);
2065
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
2066
    TC_MUTEX_LOCK(lmutex);
2067
    TC_MUTEX_UNLOCK(mutex_fsop);
2068
2069
    MDBGLOG("rdpfs","\nrdpfs_statfs(path=\"%s\")\n",
2070
	    path);
2071
2072
    cbdata = &(g_reqids[reqid]);
2073
    cbdata->userdata = (void *)g_malloc(sizeof(FILE_FS_FULL_SIZE_INFORMATION), 1);
2074
    vbuf = (FILE_FS_FULL_SIZE_INFORMATION *)(cbdata->userdata);
2075
2076
    rdpfs_fullpath(fpath,path);
2077
2078
    lfi = (struct fuse_file_info *)g_malloc(sizeof(struct fuse_file_info), 1);
2079
    rdpfs_open(path, lfi);
2080
    fhandle = lfi->fh;
2081
2082
    rdpfs_opcode = RDPFS_STATFS;
2083
    fsize = g_strlen(fpath) + 1;
2084
    uniqid = reqid;
2085
2086
    TC_MUTEX_LOCK(mutex_pcon_fs);
2087
    pcon = g_fs->ccon;
2088
    pcon->callback_data = cbdata;
2089
    s = trans_get_out_s(pcon, MAX_STREAM);
2090
    out_uint32_le(s, magic);
2091
    out_uint32_le(s, rdpfs_opcode);
2092
    out_uint32_le(s, fsize);
2093
    out_uint32_le(s, device_id);
2094
    out_uint32_le(s, fhandle);
2095
    out_uint32_le(s, uniqid);
2096
    p_crc32 = (uint32_t *)s_get_pos(s);
2097
    out_uint32_le(s, crc32);
2098
    p = (char *)s_get_pos(s);
2099
    if (fsize > 0) {
2100
      out_uint8a(s, fpath, fsize);
2101
    }
2102
    s_mark_end(s);
2103
    if (p_crc32 != NULL) {
2104
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
2105
    }
2106
    MDBGLOG("rdpfs"," ** rdpfs_statfs (about to send! fsize = %d; fpath = %s)", fsize, fpath);
2107
    fsize = s->end - s->data;
2108
    trans_force_write(pcon);
2109
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
2110
    MDBGLOG("rdpfs","sent.");
2111
2112
    MDBGLOG("rdpfs"," Entering wait loop...");
2113
    get_cv_fs(reqid,&lcv,g_fs);
2114
    TC_COND_WAIT(lcv,lmutex);
2115
    MDBGLOG("rdpfs"," Finished.");
2116
2117
    bytes_per_sector = vbuf->BytesPerSector;
2118
    sectors_per_block = vbuf->SectorsPerAllocationUnit;
2119
    bytes_per_block = bytes_per_sector * sectors_per_block;
2120
2121
    statv->f_bsize = bytes_per_block;
2122
    statv->f_blocks = vbuf->TotalAllocationUnits;
2123
    statv->f_bfree = vbuf->ActualAvailableAllocationUnits;
2124
    statv->f_bavail = vbuf->CallerAvailableAllocationUnits;
2125
    statv->f_files = statv->f_ffree = statv->f_favail = 0xffffffff;
2126
    statv->f_namemax = 255;
2127
2128
    MDBGLOG("rdpfs","STATFS: f_bsize = %d; f_blocks = %d; f_bfree = %d; f_bavail = %d; f_files = %d",statv->f_bsize,statv->f_blocks,statv->f_bfree,statv->f_bavail,statv->f_files);
2129
2130
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
2131
    if (retstat < 0) {
2132
      MDBGLOG("rdpfs","ERROR [rdpfs_statfs()]: cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR (cbdata->IoStatus.Value = 0x%8.8x)",cbdata->IoStatus.Value);
2133
    }
2134
    else {
2135
      	retstat = 0;
2136
    }
2137
    if (cbdata->userdata != NULL) {
2138
      g_free(cbdata->userdata);
2139
    }
2140
    g_memset(cbdata,0,sizeof(callback));
2141
    if (lfi != NULL) {
2142
      g_free(lfi);
2143
    }
2144
2145
    TC_MUTEX_UNLOCK(lmutex);
2146
    free_reqid_fs(reqid);
2147
2148
    return retstat;
2149
}
2150
2151
/** Possibly flush cached data
2152
 *
2153
 * BIG NOTE: This is not equivalent to fsync().  It's not a
2154
 * request to sync dirty data.
2155
 *
2156
 * Flush is called on each close() of a file descriptor.  So if a
2157
 * filesystem wants to return write errors in close() and the file
2158
 * has cached dirty data, this is a good place to write back data
2159
 * and return any errors.  Since many applications ignore close()
2160
 * errors this is not always useful.
2161
 *
2162
 * NOTE: The flush() method may be called more than once for each
2163
 * open().  This happens if more than one file descriptor refers
2164
 * to an opened file due to dup(), dup2() or fork() calls.  It is
2165
 * not possible to determine if a flush is final, so each flush
2166
 * should be treated equally.  Multiple write-flush sequences are
2167
 * relatively rare, so this shouldn't be a problem.
2168
 *
2169
 * Filesystems shouldn't assume that flush will always be called
2170
 * after some writes, or that if will be called at all.
2171
 *
2172
 * Changed in version 2.2
2173
 */
2174
int rdpfs_flush(const char * path, struct fuse_file_info * fi) {
2175
    RDPFS_DECS;
2176
    //tbus fd = -1;
2177
    int retstat = 0;
2178
    char fpath[PATH_MAX];
2179
    struct stream * s = NULL;
2180
    //struct stat st;
2181
    //ptrdiff_t idx = 0;
2182
    //tbus objs[1] = { 0x00000000 };
2183
    //size_t num_objs = 0;
2184
    ptrdiff_t fsize = 0;
2185
    struct trans * pcon = (struct trans *)NULL;
2186
    int rdpfs_opcode = 0x00000000;
2187
    int reqid = -1;
2188
    tbus fhandle = 0;
2189
    int uniqid = 0;
2190
    tbus empty_fi = 0;
2191
    struct fuse_file_info * lfi = NULL;
2192
    tc_p lmutex = (tc_p)NULL;
2193
    tc_p lcv = (tc_p)NULL;
2194
    callback * cbdata = NULL;
2195
    uint32_t crc32 = 0;
2196
    uint32_t * p_crc32 = (uint32_t *)NULL;
2197
    const uint32_t magic = RDP_PACKET_MAGIC;
2198
    char * p = (char *)NULL;
2199
2200
    TC_MUTEX_LOCK(mutex_fsop);
2201
    get_reqid_fs(&reqid);
2202
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
2203
    TC_MUTEX_LOCK(lmutex);
2204
    TC_MUTEX_UNLOCK(mutex_fsop);
2205
2206
    MDBGLOG("rdpfs","\nrdpfs_flush(path=\"%s\", fi=0x%8.8x)\n", path, fi);
2207
2208
    cbdata = &(g_reqids[reqid]);
2209
2210
    rdpfs_fullpath(fpath,path);
2211
2212
    if (fi == NULL || fi->fh < 1) {
2213
      empty_fi = 1;
2214
      lfi = (struct fuse_file_info *)g_malloc(sizeof(struct fuse_file_info), 1);
2215
      g_memcpy(lfi,fi,sizeof(struct fuse_file_info));
2216
      rdpfs_open(path,lfi);
2217
    }
2218
    else {
2219
      lfi = fi;
2220
    }
2221
    fhandle = lfi->fh;
2222
2223
    rdpfs_opcode = RDPFS_FLUSH;
2224
    fsize = g_strlen(fpath) + 1;
2225
    uniqid = reqid;
2226
2227
    TC_MUTEX_LOCK(mutex_pcon_fs);
2228
    pcon = g_fs->ccon;
2229
    pcon->callback_data = cbdata;
2230
    s = trans_get_out_s(pcon, MAX_STREAM);
2231
    out_uint32_le(s, magic);
2232
    out_uint32_le(s, rdpfs_opcode);
2233
    out_uint32_le(s, fsize);
2234
    out_uint32_le(s, device_id);
2235
    out_uint32_le(s, fhandle);
2236
    out_uint32_le(s, uniqid);
2237
    p_crc32 = (uint32_t *)s_get_pos(s);
2238
    out_uint32_le(s, crc32);
2239
    p = (char *)s_get_pos(s);
2240
    if (fsize > 0) {
2241
      out_uint8a(s, fpath, fsize);
2242
    }
2243
    s_mark_end(s);
2244
    if (p_crc32 != NULL) {
2245
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
2246
    }
2247
    MDBGLOG("rdpfs"," ** rdpfs_flush (about to send! fsize = %d; fpath = %s)", fsize, fpath);
2248
    fsize = s->end - s->data;
2249
    trans_force_write(pcon);
2250
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
2251
    MDBGLOG("rdpfs","sent.");
2252
2253
    MDBGLOG("rdpfs"," Entering wait loop...");
2254
    get_cv_fs(reqid,&lcv,g_fs);
2255
    TC_COND_WAIT(lcv,lmutex);
2256
    MDBGLOG("rdpfs"," Finished.");
2257
2258
    if (empty_fi > 0 && lfi != NULL) {
2259
      rdpfs_release(path,lfi);
2260
    }
2261
2262
    if (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR) {
2263
      MDBGLOG("rdpfs","ERROR [rdpfs_flush()]: cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR (cbdata->IoStatus.Value = 0x%8.8x)",cbdata->IoStatus.Value);
2264
      retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
2265
    }
2266
    else {
2267
      retstat = cbdata->length;
2268
    }
2269
    if (cbdata->userdata != NULL) {
2270
      g_free(cbdata->userdata);
2271
    }
2272
    g_memset(cbdata,0,sizeof(callback));
2273
2274
    TC_MUTEX_UNLOCK(lmutex);
2275
    free_reqid_fs(reqid);
2276
2277
    if (empty_fi > 0 && lfi != NULL) {
2278
      g_free(lfi);
2279
    }
2280
2281
    return retstat;
2282
}
2283
2284
/** Release an open file
2285
 *
2286
 * Release is called when there are no more references to an open
2287
 * file: all file descriptors are closed and all memory mappings
2288
 * are unmapped.
2289
 *
2290
 * For every open() call there will be exactly one release() call
2291
 * with the same flags and file descriptor.  It is possible to
2292
 * have a file opened more than once, in which case only the last
2293
 * release will mean, that no more reads/writes will happen on the
2294
 * file.  The return value of release is ignored.
2295
 *
2296
 * Changed in version 2.2
2297
 */
2298
int rdpfs_release(const char * path, struct fuse_file_info * fi) {
2299
    RDPFS_DECS;
2300
    int retstat = 0;
2301
    char fpath[PATH_MAX];
2302
    struct stream * s = NULL;
2303
    char buf[512];
2304
    struct stat st;
2305
    struct trans * pcon = (struct trans *)NULL;
2306
    int rdpfs_opcode = 0x00000000;
2307
    ptrdiff_t size = 0x00000000;
2308
    struct _rdpfs_data rdata;
2309
    tbus fhandle = 0;
2310
    int uniqid = 0;
2311
    int reqid = -1;
2312
    callback * cbdata = NULL;
2313
    tc_p lmut = (tc_p)NULL;
2314
    tc_p lcv = (tc_p)NULL;
2315
    uint32_t crc32 = 0;
2316
    uint32_t * p_crc32 = (uint32_t *)NULL;
2317
    const uint32_t magic = RDP_PACKET_MAGIC;
2318
    char * p = (char *)NULL;
2319
2320
    TC_MUTEX_LOCK(mutex_fsop);
2321
    get_reqid_fs(&reqid);
2322
    get_mutex_fs(reqid,(tc_p *)&lmut,g_fs);
2323
    TC_MUTEX_LOCK(lmut);
2324
    TC_MUTEX_UNLOCK(mutex_fsop);
2325
2326
    MDBGLOG("rdpfs","\n\nrdpfs_release(path=\"%s\")\n",path);
2327
    g_memset(&st,0,sizeof(struct stat));
2328
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2329
    g_memset(buf,0,sizeof(char)*512);
2330
    g_memset(&rdata,0,sizeof(rdpfs_data));
2331
2332
    rdpfs_fullpath(fpath, path);
2333
2334
    rdpfs_opcode = RDPFS_RELEASE;
2335
    size = g_strlen(fpath) + 1;
2336
    uniqid = reqid;
2337
    fhandle = fi->fh;
2338
    cbdata = &(g_reqids[reqid]);
2339
    cbdata->FileId = fhandle;
2340
2341
    TC_MUTEX_LOCK(mutex_pcon_fs);
2342
    pcon = g_fs->ccon;
2343
    pcon->callback_data = cbdata;
2344
    s = trans_get_out_s(pcon, MAX_STREAM);
2345
    out_uint32_le(s, magic);
2346
    out_uint32_le(s, rdpfs_opcode);
2347
    out_uint32_le(s, size);
2348
    out_uint32_le(s, device_id);
2349
    out_uint32_le(s, fhandle);
2350
    out_uint32_le(s, uniqid);
2351
    p_crc32 = (uint32_t *)s_get_pos(s);
2352
    out_uint32_le(s, crc32);
2353
    p = (char *)s_get_pos(s);
2354
    if (size > 0) {
2355
      out_uint8a(s, fpath, size);
2356
    }
2357
    s_mark_end(s);
2358
    size = s->end - s->data;
2359
    if (p_crc32 != NULL) {
2360
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
2361
    }
2362
    MDBGLOG("rdpfs"," ** rdpfs_release(): sending [g_fd = %d]", g_fd);
2363
    trans_force_write(pcon);
2364
    MDBGLOG("rdpfs","sent.");
2365
    g_memset(s->data,0,MAX_STREAM);
2366
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
2367
2368
    get_cv_fs(reqid,&lcv,g_fs);
2369
    MDBGLOG("rdpfs"," Waiting...");
2370
    TC_COND_WAIT(lcv,lmut);
2371
    MDBGLOG("rdpfs"," Done.");
2372
2373
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
2374
    if (retstat < 0) {
2375
	retstat = rdpfs_error("rdpfs_release lstat");
2376
	MDBGLOG("rdpfs","ERROR [rdpfs_release()]: retstat = %d",retstat);
2377
    }
2378
    //log_fi(fi);
2379
2380
    MDBGLOG("rdpfs","rdpfs_release(): done. ()");
2381
2382
    TC_MUTEX_UNLOCK(lmut);
2383
    free_reqid_fs(reqid);
2384
2385
    return retstat;
2386
}
2387
2388
/** Synchronize file contents
2389
 *
2390
 * If the datasync parameter is non-zero, then only the user data
2391
 * should be flushed, not the meta data.
2392
 *
2393
 * Changed in version 2.2
2394
 */
2395
int rdpfs_fsync(const char * path, int datasync, struct fuse_file_info * fi) {
2396
    RDPFS_DECS;
2397
    int retstat = 0;
2398
    //tbus fhandle = 0;
2399
    //int uniqid = 0;
2400
2401
    MDBGLOG("rdpfs","\nrdpfs_fsync(path=\"%s\", datasync=%d, fi=0x%08x)\n",
2402
	    path, datasync, fi);
2403
    //log_fi(fi);
2404
2405
    if (datasync)
2406
	retstat = fdatasync(fi->fh);
2407
    else
2408
	retstat = fsync(fi->fh);
2409
2410
    if (retstat < 0)
2411
	rdpfs_error("rdpfs_fsync fsync");
2412
2413
    return retstat;
2414
}
2415
2416
#if defined(__linux__)
2417
/** Set extended attributes */
2418
int rdpfs_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) {
2419
    RDPFS_DECS;
2420
    int retstat = 0;
2421
    char fpath[PATH_MAX];
2422
    //tbus fhandle = 0;
2423
    //int uniqid = 0;
2424
2425
    MDBGLOG("rdpfs","\nrdpfs_setxattr(path=\"%s\", name=\"%s\", value=\"%s\", size=%d, flags=0x%08x)\n",
2426
	    path, name, value, size, flags);
2427
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2428
    rdpfs_fullpath(fpath, path);
2429
2430
    //retstat = lsetxattr(fpath, name, value, size, flags);
2431
    if (retstat < 0)
2432
	retstat = rdpfs_error("rdpfs_setxattr lsetxattr");
2433
2434
    return retstat;
2435
}
2436
2437
/** Get extended attributes */
2438
int rdpfs_getxattr(const char * ipath, const char * iname, char * ivalue, size_t size) {
2439
    RDPFS_DECS;
2440
    int retstat = 0;
2441
    char fpath[PATH_MAX];
2442
    //tbus fhandle = 0;
2443
    //int uniqid = 0;
2444
    char * path = (char *)NULL;
2445
    char * name = (char *)NULL;
2446
    char * value = (char *)NULL;
2447
    struct fuse_file_info lfi;
2448
    struct fuse_file_info * fi = &lfi;
2449
    FILE_OBJECTID_BUFFER lbuf;
2450
    RETRIEVAL_POINTERS_BUFFER lrpn;
2451
    void * buf = NULL;
2452
2453
    path = (char *)g_strdup(ipath);
2454
    name = (char *)g_strdup(iname);
2455
    value = (char *)g_strdup(ivalue);
2456
2457
    MDBGLOG("rdpfs","\nrdpfs_getxattr(path = \"%s\", name = \"%s\", value = \"%s\", size = %d)\n", path, name, value, size);
2458
2459
    g_memset(&lbuf,0,sizeof(FILE_OBJECTID_BUFFER));
2460
    g_memset(&lrpn,0,sizeof(RETRIEVAL_POINTERS_BUFFER));
2461
    g_memset(&lfi,0,sizeof(struct fuse_file_info));
2462
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2463
    rdpfs_fullpath(fpath, path);
2464
2465
    fi->flags |= O_RDONLY;
2466
    rdpfs_open(path, fi);
2467
2468
    if (!g_strcasecmp(name,"oid")) {
2469
      char tmp[20] = "";
2470
      const uint32_t cmd = FSCTL_GET_OBJECT_ID;
2471
      g_memset(tmp,0,sizeof(char) * 20);
2472
      buf = &lbuf;
2473
      rdpfs_fsctl(path,fi,cmd,0,buf);
2474
      g_snprintf(tmp,19,"0x%8.8x",((BYTE *)buf)[0]);
2475
      g_memcpy(ivalue,tmp,MIN(20,size));
2476
    }
2477
    else if (!g_strcasecmp(name,"mft")) {
2478
      char tmp[20] = "";
2479
      const uint32_t cmd = FSCTL_GET_RETRIEVAL_POINTERS;
2480
      BYTE tout[128];
2481
      QWORD blah = 5;
2482
      g_memset(tmp,0,sizeof(char) * 20);
2483
      g_memset(tout,0,sizeof(BYTE) * 128);
2484
      g_memcpy(tout,&blah,8);
2485
      buf = tout;
2486
      rdpfs_fsctl(path,fi,cmd,8,buf);
2487
      g_snprintf(tmp,19,"0x%8.8x",((BYTE *)buf)[0]);
2488
      g_memcpy(ivalue,tmp,MIN(20,size));
2489
      g_memcpy(&lrpn,buf,32);
2490
      MDBGLOG("rdpfs"," ** RESULTS: ExtentCount = %d; StartingVcn = %lld",lrpn.ExtentCount,lrpn.StartingVcn);
2491
    }
2492
2493
    rdpfs_release(path, fi);
2494
2495
    MDBGLOG("rdpfs","rdpfs_getxattr(): value = \"%s\"\n", value);
2496
2497
    return retstat;
2498
}
2499
2500
/** List extended attributes */
2501
int rdpfs_listxattr(const char *path, char *list, size_t size) {
2502
    RDPFS_DECS;
2503
    int retstat = 0;
2504
    char fpath[PATH_MAX];
2505
    char *ptr;
2506
    //tbus fhandle = 0;
2507
    //int uniqid = 0;
2508
2509
    MDBGLOG("rdpfs","rdpfs_listxattr(path=\"%s\", list=0x%08x, size=%d)\n",
2510
	    path, list, size
2511
	    );
2512
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2513
    rdpfs_fullpath(fpath, path);
2514
2515
    //retstat = llistxattr(fpath, list, size);
2516
    if (retstat < 0)
2517
	retstat = rdpfs_error("rdpfs_listxattr llistxattr");
2518
2519
    MDBGLOG("rdpfs","    returned attributes (length %d):\n", retstat);
2520
    for (ptr = list; ptr < list + retstat; ptr += strlen(ptr)+1)
2521
	MDBGLOG("rdpfs","    \"%s\"\n", ptr);
2522
2523
    return retstat;
2524
}
2525
2526
/** Remove extended attributes */
2527
int rdpfs_removexattr(const char *path, const char *name) {
2528
    RDPFS_DECS;
2529
    int retstat = 0;
2530
    char fpath[PATH_MAX];
2531
    //tbus fhandle = 0;
2532
    //int uniqid = 0;
2533
2534
    MDBGLOG("rdpfs","\nrdpfs_removexattr(path=\"%s\", name=\"%s\")\n",
2535
	    path, name);
2536
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2537
    rdpfs_fullpath(fpath, path);
2538
2539
    //retstat = lremovexattr(fpath, name);
2540
    if (retstat < 0)
2541
	retstat = rdpfs_error("rdpfs_removexattr lrmovexattr");
2542
2543
    return retstat;
2544
}
2545
#endif
2546
2547
/** Open directory
2548
 *
2549
 * This method should check if the open operation is permitted for
2550
 * this  directory
2551
 *
2552
 * Introduced in version 2.3
2553
 */
2554
int rdpfs_opendir(const char * path, struct fuse_file_info * fi) {
2555
    RDPFS_DECS;
2556
    int retstat = 0;
2557
    //tbus fd = -1;
2558
    char fpath[PATH_MAX];
2559
    struct stream * s = NULL;
2560
    char buf[512];
2561
    struct stat st;
2562
    //ptrdiff_t idx = 0;
2563
    //tbus objs[1] = { 0x00000000 };
2564
    //size_t num_objs = 0;
2565
    //int timeout = 0;
2566
    struct trans * pcon = (struct trans *)NULL;
2567
    int rdpfs_opcode = 0x00000000;
2568
    ptrdiff_t size = 0x00000000;
2569
    struct _rdpfs_data rdata;
2570
    tc_p lmutex = (tc_p)NULL;
2571
    tc_p lcv = (tc_p)NULL;
2572
    callback * cbdata = NULL;
2573
    int reqid = -1;
2574
    tbus fhandle = 0;
2575
    int uniqid = 0;
2576
    uint32_t crc32 = 0;
2577
    uint32_t * p_crc32 = (uint32_t *)NULL;
2578
    const uint32_t magic = RDP_PACKET_MAGIC;
2579
    char * p = (char *)NULL;
2580
2581
    TC_MUTEX_LOCK(mutex_fsop);
2582
    get_reqid_fs(&reqid);
2583
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
2584
    TC_MUTEX_LOCK(lmutex);
2585
    TC_MUTEX_UNLOCK(mutex_fsop);
2586
2587
    MDBGLOG("rdpfs","\n\nrdpfs_opendir(path=\"%s\")\n",path);
2588
2589
    g_memset(&st,0,sizeof(struct stat));
2590
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2591
    g_memset(buf,0,sizeof(char)*512);
2592
    g_memset(&rdata,0,sizeof(rdpfs_data));
2593
2594
    rdpfs_fullpath(fpath, path);
2595
2596
    get_cv_fs(reqid, &lcv,g_fs);
2597
    cbdata = &(g_reqids[reqid]);
2598
2599
    rdpfs_opcode = RDPFS_OPENDIR;
2600
    size = g_strlen(fpath) + 1;
2601
    uniqid = reqid;
2602
2603
    TC_MUTEX_LOCK(mutex_pcon_fs);
2604
    pcon = g_fs->ccon;
2605
    pcon->callback_data = cbdata;
2606
    s = trans_get_out_s(pcon, MAX_STREAM);
2607
    out_uint32_le(s, magic);
2608
    out_uint32_le(s, rdpfs_opcode);
2609
    out_uint32_le(s, size);
2610
    out_uint32_le(s, device_id);
2611
    out_uint32_le(s, fhandle);
2612
    out_uint32_le(s, uniqid);
2613
    p_crc32 = (uint32_t *)s_get_pos(s);
2614
    out_uint32_le(s, crc32);
2615
    p = (char *)s_get_pos(s);
2616
    if (size > 0) {
2617
      out_uint8a(s, fpath, size);
2618
    }
2619
    s_mark_end(s);
2620
    if (p_crc32 != NULL) {
2621
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
2622
    }
2623
    size = s->end - s->data;
2624
2625
    MDBGLOG("rdpfs"," ** rdpfs_opendir(): sending [g_fd = %d]", g_fd);
2626
    trans_force_write(pcon);
2627
    MDBGLOG("rdpfs","sent.");
2628
    g_memset(s->data,0,MAX_STREAM);
2629
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
2630
2631
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
2632
    TC_COND_WAIT(lcv, lmutex);
2633
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
2634
2635
    fhandle = cbdata->FileId;
2636
2637
    if (retstat != 0) {
2638
      retstat = rdpfs_error("rdpfs_opendir lstat");
2639
      MDBGLOG("rdpfs","ERROR [rdpfs_opendir()]: retstat = %d",retstat);
2640
    }
2641
2642
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
2643
    if (retstat < 0) {
2644
      MDBGLOG("rdpfs","ERROR [rdpfs_opendir()]: retstat = %d; cbdata->IoStatus.Value = 0x%8.8x",retstat,cbdata->IoStatus.Value);
2645
    }
2646
    fi->fh = fhandle;
2647
    //log_fi(fi);
2648
2649
    MDBGLOG("rdpfs","rdpfs_opendir(): done. (fi->fh = %d; retstat = %d)",fi->fh,retstat);
2650
2651
    TC_MUTEX_UNLOCK(lmutex);
2652
    free_reqid_fs(reqid);
2653
2654
    return retstat;
2655
}
2656
2657
/** Read directory
2658
 *
2659
 * This supersedes the old getdir() interface.  New applications
2660
 * should use this.
2661
 *
2662
 * The filesystem may choose between two modes of operation:
2663
 *
2664
 * 1) The readdir implementation ignores the offset parameter, and
2665
 * passes zero to the filler function's offset.  The filler
2666
 * function will not return '1' (unless an error happens), so the
2667
 * whole directory is read in a single readdir operation.  This
2668
 * works just like the old getdir() method.
2669
 *
2670
 * 2) The readdir implementation keeps track of the offsets of the
2671
 * directory entries.  It uses the offset parameter and always
2672
 * passes non-zero offset to the filler function.  When the buffer
2673
 * is full (or an error happens) the filler function will return
2674
 * '1'.
2675
 *
2676
 * Introduced in version 2.3
2677
 */
2678
int rdpfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
2679
    RDPFS_DECS;
2680
    int retstat = 0;
2681
    //tbus fd = -1;
2682
    DIR * dp = (DIR *)NULL;
2683
    char fpath[PATH_MAX];
2684
    struct stream * s = NULL;
2685
    struct stat st;
2686
    ptrdiff_t idx = 0;
2687
    struct trans * pcon = (struct trans *)NULL;
2688
    int rdpfs_opcode = 0x00000000;
2689
    ptrdiff_t size = 0x00000000;
2690
    struct fuse_file_info * lfi = (struct fuse_file_info *)NULL;
2691
    callback * cbdata = (callback *)NULL;
2692
    filelist * lst = (filelist *)NULL;
2693
    tc_p lmutex = (tc_p)NULL;
2694
    tc_p lcv = (tc_p)NULL;
2695
    int reqid = -1;
2696
    tbus fhandle = 0;
2697
    int uniqid = 0;
2698
    tbus empty_fi_fh = 0;
2699
    uint32_t crc32 = 0;
2700
    uint32_t * p_crc32 = (uint32_t *)NULL;
2701
    const uint32_t magic = RDP_PACKET_MAGIC;
2702
    char * p = (char *)NULL;
2703
2704
    /*									*/
2705
    /* lock access by other threads:					*/
2706
    TC_MUTEX_LOCK(mutex_fsop);
2707
    get_reqid_fs(&reqid);
2708
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
2709
    TC_MUTEX_LOCK(lmutex);
2710
    TC_MUTEX_UNLOCK(mutex_fsop);
2711
2712
    MDBGLOG("rdpfs","\n\nrdpfs_readdir(path=\"%s\")\n",path);
2713
    g_memset(&st,0,sizeof(struct stat));
2714
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2715
2716
    rdpfs_opcode = RDPFS_READDIR;
2717
    uniqid = reqid;
2718
2719
    cbdata = (callback *)(&(g_reqids[reqid]));
2720
    cbdata->opid = reqid;
2721
    cbdata->uniqid = uniqid;
2722
    cbdata->opcode = rdpfs_opcode;
2723
    cbdata->fs = g_fs;
2724
    cbdata->trans = (cbdata->fs == NULL) ? (struct trans *)NULL : cbdata->fs->ccon;
2725
    cbdata->fd = (cbdata->trans == NULL) ? -1 : cbdata->trans->sck;
2726
    cbdata->type = (cbdata->trans == NULL) ? 0 : -1;
2727
    cbdata->length = sizeof(filelist);
2728
    cbdata->userdata = (BYTE *)g_malloc(sizeof(BYTE) * cbdata->length, 1);
2729
    idx = g_strlen(path);
2730
    lst = (filelist *)(cbdata->userdata);
2731
    g_memcpy(cbdata->fname,path,(idx > 511)?511:idx);
2732
    if (fi != NULL) {
2733
      dp = (DIR *)(uintptr_t) fi->fh;
2734
    }
2735
    else {
2736
      empty_fi_fh = 1;
2737
      lfi = (struct fuse_file_info *)g_malloc(sizeof(struct fuse_file_info), 1);
2738
      rdpfs_opendir(path, lfi);
2739
      dp = (DIR *)(uintptr_t) lfi->fh;
2740
    }
2741
    rdpfs_fullpath(fpath,path);
2742
    fhandle = (int)(uintptr_t)dp;
2743
    cbdata->FileId = fhandle;
2744
    size = g_strlen(fpath) + 1;
2745
2746
    TC_MUTEX_LOCK(mutex_pcon_fs);
2747
    pcon = g_fs->ccon;
2748
    s = trans_get_out_s(pcon, MAX_STREAM);
2749
    out_uint32_le(s, magic);
2750
    out_uint32_le(s, rdpfs_opcode);
2751
    out_uint32_le(s, size);
2752
    out_uint32_le(s, device_id);
2753
    out_uint32_le(s, fhandle);
2754
    out_uint32_le(s, uniqid);
2755
    p_crc32 = (uint32_t *)s_get_pos(s);
2756
    out_uint32_le(s, crc32);
2757
    p = (char *)s_get_pos(s);
2758
    if (size > 0) {
2759
      out_uint8a(s, fpath, size);
2760
    }
2761
    s_mark_end(s);
2762
    size = s->end - s->data;
2763
    if (p_crc32 != NULL) {
2764
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
2765
    }
2766
    pcon->callback_data = (void *)(cbdata);
2767
    MDBGLOG("rdpfs"," ** rdpfs_readdir(): sending [g_fd = %d; fhandle = %d]", g_fd, fhandle);
2768
    trans_force_write(pcon);
2769
    g_memset(s->data,0,MAX_STREAM);
2770
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
2771
    MDBGLOG("rdpfs","sent.");
2772
2773
    MDBGLOG("rdpfs","INFO\t[%s()]: entering g_obj_wait loop:", __func__);
2774
    get_cv_fs(reqid, &lcv,g_fs);
2775
    TC_COND_WAIT(lcv, lmutex);
2776
    MDBGLOG("rdpfs","INFO\t[%s()]: exiting g_obj_wait loop. (lst->count = %d)", __func__, lst->count);
2777
2778
    filler(buf, ".", NULL, 0);
2779
    filler(buf, "..", NULL, 0);
2780
    for (idx = 0; idx < lst->count; idx++) {
2781
      char * tfname = (char *)NULL;
2782
      struct stat tst;
2783
      struct stat * st = &tst;
2784
      if (lst->files[idx]->filename != NULL && g_strlen(lst->files[idx]->filename) > 0 && (lst->files[idx]->filename)[0] != '.') {
2785
	tfname = lst->files[idx]->filename;
2786
      }
2787
      if (tfname != NULL) {
2788
	g_memset(&tst,0,sizeof(struct stat));
2789
	st->st_dev   = 0x00000801;
2790
	if ((lst->files[idx]->FileAttributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) {
2791
	  st->st_mode = 0644;
2792
	}
2793
	else {
2794
	  st->st_mode = 0755;
2795
	}
2796
	st->st_ctime = FileTimeToUnix(lst->files[idx]->CreationTime);
2797
	st->st_mtime = FileTimeToUnix(lst->files[idx]->LastWriteTime);
2798
	st->st_atime = FileTimeToUnix(lst->files[idx]->LastAccessTime);
2799
	st->st_size = lst->files[idx]->EndOfFile;
2800
	st->st_blocks = lst->files[idx]->AllocationSize;
2801
	if (lst->files[idx]->Directory > 0) {
2802
	  /* set the "directory" flag: */
2803
	  st->st_mode |= S_IFDIR;
2804
	  st->st_nlink = 1;
2805
	}
2806
	else if ((lst->files[idx]->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && rdpfs_is_blk_file(tfname) > 0) {
2807
	  /*
2808
	   * if the above test is true, then this is an Interix-type block device file:
2809
	   */
2810
	  st->st_mode |= S_IFBLK;
2811
	  st->st_rdev |= rdpfs_is_blk_file(tfname);
2812
	  st->st_nlink = 1;
2813
	  st->st_size = 0;
2814
	  st->st_blocks = 0;
2815
	}
2816
	else if ((lst->files[idx]->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && rdpfs_is_chr_file(tfname) > 0) {
2817
	  /*
2818
	   * if the above test is true, then this is an Interix-type character device file:
2819
	   */
2820
	  st->st_mode |= S_IFCHR;
2821
	  st->st_rdev |= rdpfs_is_chr_file(tfname);
2822
	  st->st_nlink = 1;
2823
	  st->st_size = 0;
2824
	  st->st_blocks = 0;
2825
	}
2826
	else if ((lst->files[idx]->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && lst->files[idx]->EndOfFile == 0) {
2827
	  /*
2828
	   * if the above test is true, then this is an Interix-type FIFO (named pipe):
2829
	   */
2830
	  st->st_mode |= S_IFIFO;
2831
	  st->st_nlink = 1;
2832
	  st->st_size = 0;
2833
	  st->st_blocks = 0;
2834
	}
2835
	else if ((lst->files[idx]->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && lst->files[idx]->EndOfFile == 1) {
2836
	  /*
2837
	   * if the above test is true, then this is an Interix-type socket:
2838
	   */
2839
	  st->st_mode |= S_IFSOCK;
2840
	  st->st_nlink = 1;
2841
	  st->st_size = 0;
2842
	  st->st_blocks = 0;
2843
	}
2844
	else if ((lst->files[idx]->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && lst->files[idx]->EndOfFile > 5 && lst->files[idx]->EndOfFile < 2048 && tfname != NULL && rdpfs_is_symlink(tfname) > 0) {
2845
	  /*
2846
	   * if the above test is true, then this is a "Minshall-French"-type symlink:
2847
	   */
2848
	  st->st_mode |= S_IFLNK;
2849
	  st->st_nlink = 1;
2850
	}
2851
	else {
2852
	  /* set the "regular file" flag: */
2853
	  st->st_mode |= S_IFREG;
2854
	  st->st_nlink = 1;
2855
	}
2856
	MDBGLOG("rdpfs","calling filler with name %s", lst->files[idx]->filename);
2857
	if (filler(buf, lst->files[idx]->filename, st, 0) != 0) {
2858
	  TC_MUTEX_UNLOCK(lmutex);
2859
	  free_reqid_fs(reqid);
2860
	  return -ENOMEM;
2861
	}
2862
      }
2863
      if (lst->files[idx] != NULL) {
2864
	g_free(lst->files[idx]);
2865
      }
2866
    }
2867
    if (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR) {
2868
      retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
2869
    }
2870
    if (retstat < 0) {
2871
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
2872
      retstat = rdpfs_error("rdpfs_readdir lstat");
2873
      MDBGLOG("rdpfs","ERROR [rdpfs_readdir()]: \"%s\" (retstat = %d)",nterr,retstat);
2874
    }
2875
    //log_fi(fi);
2876
2877
    if (cbdata->userdata != NULL) {
2878
      g_free(cbdata->userdata);
2879
    }
2880
    g_memset(cbdata,0,sizeof(callback));
2881
2882
    if (empty_fi_fh > 0 && lfi != NULL && lfi->fh > -1) {
2883
      rdpfs_releasedir(path, lfi);
2884
      g_free(lfi);
2885
    }
2886
2887
    TC_MUTEX_UNLOCK(lmutex);
2888
    free_reqid_fs(reqid);
2889
    return retstat;
2890
}
2891
2892
/** Release directory
2893
 *
2894
 * Introduced in version 2.3
2895
 */
2896
static int rdpfs_releasedir(const char * path, struct fuse_file_info * fi) {
2897
    RDPFS_DECS;
2898
    int retstat = 0;
2899
    //tbus fd = -1;
2900
    char fpath[PATH_MAX];
2901
    struct stream * s = NULL;
2902
    char buf[512];
2903
    struct stat st;
2904
    //ptrdiff_t idx = 0;
2905
    //tbus objs[1] = { 0x00000000 };
2906
    //size_t num_objs = 0;
2907
    //int timeout = 0;
2908
    struct trans * pcon = (struct trans *)NULL;
2909
    int rdpfs_opcode = 0x00000000;
2910
    ptrdiff_t size = 0x00000000;
2911
    struct _rdpfs_data rdata;
2912
    tbus fhandle = 0;
2913
    int uniqid = 0;
2914
    int reqid = -1;
2915
    callback * cbdata = NULL;
2916
    tc_p lmut = (tc_p)NULL;
2917
    tc_p lcv = (tc_p)NULL;
2918
    uint32_t crc32 = 0;
2919
    uint32_t * p_crc32 = (uint32_t *)NULL;
2920
    const uint32_t magic = RDP_PACKET_MAGIC;
2921
    char * p = (char *)NULL;
2922
2923
    TC_MUTEX_LOCK(mutex_fsop);
2924
    get_reqid_fs(&reqid);
2925
    get_mutex_fs(reqid,(tc_p *)&lmut,g_fs);
2926
    TC_MUTEX_LOCK(lmut);
2927
    TC_MUTEX_UNLOCK(mutex_fsop);
2928
2929
    MDBGLOG("rdpfs","\n\nrdpfs_releasedir(path=\"%s\")\n",path);
2930
    g_memset(&st,0,sizeof(struct stat));
2931
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
2932
    g_memset(buf,0,sizeof(char)*512);
2933
    g_memset(&rdata,0,sizeof(rdpfs_data));
2934
2935
    rdpfs_fullpath(fpath, path);
2936
2937
    rdpfs_opcode = RDPFS_RELEASEDIR;
2938
    size = g_strlen(fpath) + 1;
2939
    fhandle = fi->fh;
2940
    uniqid = reqid;
2941
2942
    cbdata = (callback *)(&(g_reqids[reqid]));
2943
2944
    TC_MUTEX_LOCK(mutex_pcon_fs);
2945
    pcon = g_fs->ccon;
2946
    pcon->callback_data = cbdata;
2947
    s = trans_get_out_s(pcon, MAX_STREAM);
2948
    out_uint32_le(s, magic);
2949
    out_uint32_le(s, rdpfs_opcode);
2950
    out_uint32_le(s, size);
2951
    out_uint32_le(s, device_id);
2952
    out_uint32_le(s, fhandle);
2953
    out_uint32_le(s, uniqid);
2954
    p_crc32 = (uint32_t *)s_get_pos(s);
2955
    out_uint32_le(s, crc32);
2956
    p = (char *)s_get_pos(s);
2957
    if (size > 0) {
2958
      out_uint8a(s, fpath, size);
2959
    }
2960
    s_mark_end(s);
2961
    size = s->end - s->data;
2962
    if (p_crc32 != NULL) {
2963
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
2964
    }
2965
    MDBGLOG("rdpfs"," ** rdpfs_releasedir(): sending [g_fd = %d]", g_fd);
2966
    trans_force_write(pcon);
2967
    MDBGLOG("rdpfs","sent.");
2968
    g_memset(s->data,0,MAX_STREAM);
2969
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
2970
2971
    MDBGLOG("rdpfs"," Waiting...");
2972
    get_cv_fs(reqid,&lcv,g_fs);
2973
    TC_COND_WAIT(lcv,lmut);
2974
    MDBGLOG("rdpfs"," Done.");
2975
2976
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
2977
    if (retstat < 0) {
2978
	char * nterr = ntstatus_string(cbdata->IoStatus.Value);
2979
	rdpfs_error("rdpfs_releasedir lstat");
2980
	MDBGLOG("rdpfs","ERROR [rdpfs_releasedir()]: \"%s\" (retstat = %d)",nterr,retstat);
2981
    }
2982
    fi->fh = 0;
2983
    //log_fi(fi);
2984
    g_memset(cbdata,0,sizeof(callback));
2985
2986
    MDBGLOG("rdpfs","rdpfs_releasedir(): done. ()");
2987
2988
    TC_MUTEX_UNLOCK(lmut);
2989
    free_reqid_fs(reqid);
2990
2991
    return retstat;
2992
}
2993
2994
/** Synchronize directory contents
2995
 *
2996
 * If the datasync parameter is non-zero, then only the user data
2997
 * should be flushed, not the meta data
2998
 *
2999
 * Introduced in version 2.3
3000
 */
3001
// when exactly is this called?  when a user calls fsync and it
3002
// happens to be a directory? ???
3003
int rdpfs_fsyncdir(const char *path, int datasync, struct fuse_file_info *fi) {
3004
    RDPFS_DECS;
3005
    int retstat = 0;
3006
    //tbus fhandle = 0;
3007
    //int uniqid = 0;
3008
3009
    MDBGLOG("rdpfs","\nrdpfs_fsyncdir(path=\"%s\", datasync=%d, fi=0x%08x)\n", path, datasync, fi);
3010
    //log_fi(fi);
3011
3012
    return retstat;
3013
}
3014
3015
/**
3016
 * Initialize filesystem
3017
 *
3018
 * The return value passes a pointer to the private_data field of
3019
 * fuse_context to all file operations and as a parameter to the
3020
 * destroy() method.
3021
 *
3022
 * Introduced in version 2.3
3023
 * Changed in version 2.6
3024
 *
3025
 *   Undocumented but extraordinarily useful fact:  the fuse_context is
3026
 *   set up before this function is called, and
3027
 *   fuse_get_context()->private_data returns the user_data passed to
3028
 *   fuse_main().  Really seems like either it should be a third
3029
 *   parameter coming in here, or else the fact should be documented
3030
 *   (and this might as well return void, as it did in older versions of
3031
 *   FUSE).
3032
 */
3033
void * rdpfs_init(struct fuse_conn_info * conn) {
3034
    RDPFS_DECS;
3035
    //tbus fd = -1;
3036
    int retstat = 0;
3037
    //char fpath[PATH_MAX];
3038
    struct stream * s = NULL;
3039
    //char buf[512];
3040
    //struct stat st;
3041
    //ptrdiff_t idx = 0;
3042
    //tbus objs[1] = { 0x00000000 };
3043
    //size_t num_objs = 0;
3044
    //int timeout = 0;
3045
    struct trans * pcon = (struct trans *)NULL;
3046
    int rdpfs_opcode = 0x00000000;
3047
    ptrdiff_t size = 0x00000000;
3048
    tbus fhandle = 0;
3049
    int uniqid = 0;
3050
    uint32_t crc32 = 0;
3051
    uint32_t * p_crc32 = (uint32_t *)NULL;
3052
    const uint32_t magic = RDP_PACKET_MAGIC;
3053
    char * p = (char *)NULL;
3054
3055
    callback * cbdata = (callback *)NULL;
3056
    tc_p lmutex = (tc_p)NULL;
3057
    tc_p lcv = (tc_p)NULL;
3058
    int reqid = -1;
3059
3060
    TC_MUTEX_LOCK(mutex_fsop);
3061
    get_reqid_fs(&reqid);
3062
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
3063
    TC_MUTEX_LOCK(lmutex);
3064
    TC_MUTEX_UNLOCK(mutex_fsop);
3065
3066
    MDBGLOG("rdpfs","INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
3067
3068
    get_cv_fs(reqid, &lcv,g_fs);
3069
    rdpfs_opcode = RDPFS_INIT;
3070
    size = 0;
3071
    uniqid = reqid;
3072
3073
    if (g_fs != NULL) {
3074
      device_id = g_fs->device_id;
3075
      g_rdpfs = g_fs;
3076
    }
3077
3078
    MDBGLOG("rdpfs", "INFO\t[%s()]: device_id = %d; g_fs = %p [%d, %d]", __func__, device_id, g_fs, g_getpid(), g_gettid());
3079
3080
    TC_MUTEX_LOCK(mutex_pcon_fs);
3081
    pcon = g_fs->ccon;
3082
    s = trans_get_out_s(pcon, MAX_STREAM);
3083
    out_uint32_le(s, magic);
3084
    out_uint32_le(s, rdpfs_opcode);
3085
    out_uint32_le(s, size);
3086
    out_uint32_le(s, device_id);
3087
    out_uint32_le(s, fhandle);
3088
    out_uint32_le(s, uniqid);
3089
    p_crc32 = (uint32_t *)s_get_pos(s);
3090
    out_uint32_le(s, crc32);
3091
    p = (char *)s_get_pos(s);
3092
    s_mark_end(s);
3093
    size = s->end - s->data;
3094
    if (p_crc32 != NULL) {
3095
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
3096
    }
3097
3098
    get_cbdata_fs(reqid, &cbdata);
3099
    cbdata->fs = g_fs;
3100
    cbdata->device_id = device_id;
3101
    cbdata->opcode = rdpfs_opcode;
3102
    pcon->callback_data = cbdata;
3103
3104
3105
    MDBGLOG("rdpfs","INFO\t[%s()]: sending (g_fd = %d, crc32 = 0x%8.8x, pcon = %p, pcon->sck = %d, lcv = %p, cbdata = %p) [%d, %d]", __func__, g_fd, *p_crc32, pcon, pcon->sck, lcv, cbdata, g_getpid(), g_gettid());
3106
    if (cbdata != NULL) {
3107
      MDBGLOG("rdpfs","INFO\t[%s()]: (cbdata->magic = 0x%8.8x) [%d, %d]", __func__, cbdata->magic, g_getpid(), g_gettid());
3108
    }
3109
    trans_force_write(pcon);
3110
    g_memset(s->data,0,MAX_STREAM);
3111
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
3112
    MDBGLOG("rdpfs", "INFO\t[%s()]: sent. [%d, %d]", __func__, g_getpid(), g_gettid());
3113
3114
    MDBGLOG("rdpfs","INFO\t[%s()]: entering g_obj_wait loop: (lcv = %p, lmutex = %p) [%d, %d]",__func__,(void *)lcv,(void *)lmutex, g_getpid(), g_gettid());
3115
    TC_COND_WAIT(lcv, lmutex);
3116
    MDBGLOG("rdpfs","INFO\t[%s()]: exiting g_obj_wait loop. [%d, %d]", __func__, g_getpid(), g_gettid());
3117
3118
    MDBGLOG("rdpfs","INFO\t[%s()]: done. [%d, %d]", __func__, g_getpid(), g_gettid());
3119
3120
    if (retstat < 0 || cbdata->IoStatus.Value >= STATUS_UNSUCCESSFUL) {
3121
      char * nterr = (char *)NULL;
3122
      if (cbdata->IoStatus.Value >= STATUS_UNSUCCESSFUL) {
3123
	retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
3124
	nterr = ntstatus_string(cbdata->IoStatus.Value);
3125
      }
3126
      if (nterr != NULL) {
3127
	MDBGLOG("rdpfs","ERROR\t[%s()]: \"%s\" (retstat = %d) [%d, %d]",__func__,nterr,retstat, g_getpid(), g_gettid());
3128
      }
3129
      else {
3130
	MDBGLOG("rdpfs","ERROR\t[%s()]: retstat = %d [%d, %d]",__func__,retstat, g_getpid(), g_gettid());
3131
      }
3132
    }
3133
3134
    TC_MUTEX_UNLOCK(lmutex);
3135
    free_reqid_fs(reqid);
3136
3137
    MDBGLOG("rdpfs", "INFO\t[%s()]: done. [%d, %d]", __func__, g_getpid(), g_gettid());
3138
    return RDPFS_DATA;
3139
}
3140
3141
/**
3142
 * Clean up filesystem
3143
 *
3144
 * Called on filesystem exit.
3145
 *
3146
 * Introduced in version 2.3
3147
 */
3148
void rdpfs_destroy(void *userdata) {
3149
    MDBGLOG("rdpfs","\nrdpfs_destroy(userdata=0x%08x)\n", userdata);
3150
3151
    TC_MUTEX_DEINIT(mutex_fsop);
3152
    TC_COND_DEINIT(cv_readdir);
3153
}
3154
3155
/**
3156
 * Check file access permissions
3157
 *
3158
 * This will be called for the access() system call.  If the
3159
 * 'default_permissions' mount option is given, this method is not
3160
 * called.
3161
 *
3162
 * This method is not called under Linux kernel versions 2.4.x
3163
 *
3164
 * Introduced in version 2.5
3165
 */
3166
static int rdpfs_access(const char * path, int mask) {
3167
    RDPFS_DECS;
3168
    int retstat = 0;
3169
    //tbus fd = -1;
3170
    DIR * dp = (DIR *)NULL;
3171
    char fpath[PATH_MAX];
3172
    struct stream * s = NULL;
3173
    char buf[512];
3174
    struct stat st;
3175
    //ptrdiff_t idx = 0;
3176
    //tbus objs[1] = { 0x00000000 };
3177
    //size_t num_objs = 0;
3178
    //int timeout = 0;
3179
    struct trans * pcon = (struct trans *)NULL;
3180
    int rdpfs_opcode = 0x00000000;
3181
    ptrdiff_t size = 0x00000000;
3182
    int reqid = -1;
3183
    tbus fhandle = 0;
3184
    int uniqid = 0;
3185
    struct fuse_file_info * lfi = NULL;
3186
    tc_p lmutex = (tc_p)NULL;
3187
    //tc_p lcv = (tc_p)NULL;
3188
    callback * cbdata = NULL;
3189
    uint32_t crc32 = 0;
3190
    uint32_t * p_crc32 = (uint32_t *)NULL;
3191
    const uint32_t magic = RDP_PACKET_MAGIC;
3192
    char * p = (char *)NULL;
3193
3194
    MDBGLOG("rdpfs","\nrdpfs_access(path=\"%s\", mask=0%o)\n", path, mask);
3195
3196
    g_memset(&st,0,sizeof(struct stat));
3197
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
3198
    g_memset(buf,0,sizeof(char)*512);
3199
3200
    lfi = (struct fuse_file_info *)g_malloc(sizeof(struct fuse_file_info), 1);
3201
    dp = (DIR *)(uintptr_t) lfi->fh;
3202
    fhandle = (int)(uintptr_t)dp;
3203
3204
    TC_MUTEX_LOCK(mutex_fsop);
3205
    get_reqid_fs(&reqid);
3206
    get_mutex_fs(reqid,(tc_p *)&lmutex,g_fs);
3207
    TC_MUTEX_LOCK(lmutex);
3208
    TC_MUTEX_UNLOCK(mutex_fsop);
3209
3210
    rdpfs_opcode = RDPFS_ACCESS;
3211
    rdpfs_fullpath(fpath, path);
3212
    size = g_strlen(fpath) + 1;
3213
    uniqid = reqid;
3214
3215
    cbdata = &(g_reqids[reqid]);
3216
    cbdata->uniqid = uniqid;
3217
    cbdata->FileId = fhandle;
3218
3219
    TC_MUTEX_LOCK(mutex_pcon_fs);
3220
    pcon = g_fs->ccon;
3221
    pcon->callback_data = cbdata;
3222
    s = trans_get_out_s(pcon, MAX_STREAM);
3223
    out_uint32_le(s, magic);
3224
    out_uint32_le(s, rdpfs_opcode);
3225
    out_uint32_le(s, size);
3226
    out_uint32_le(s, device_id);
3227
    out_uint32_le(s, fhandle);
3228
    out_uint32_le(s, uniqid);
3229
    p_crc32 = (uint32_t *)s_get_pos(s);
3230
    out_uint32_le(s, crc32);
3231
    p = (char *)s_get_pos(s);
3232
    if (size > 0) {
3233
      out_uint8a(s, fpath, size);
3234
    }
3235
    s_mark_end(s);
3236
    size = s->end - s->data;
3237
3238
    if (p_crc32 != NULL) {
3239
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
3240
    }
3241
3242
    MDBGLOG("rdpfs"," ** rdpfs_access(): sending [g_fd = %d; pcon->sck = %d; FileId = %d; uniqid = %d]", g_fd, pcon->sck, cbdata->FileId, cbdata->uniqid);
3243
    //trans_force_write(pcon);
3244
    g_memset(s->data,0,MAX_STREAM);
3245
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
3246
    MDBGLOG("rdpfs","sent.");
3247
3248
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
3249
    //get_cv_fs(reqid,&lcv,g_fs);
3250
    //TC_COND_WAIT(lcv, lmutex);
3251
    MDBGLOG("rdpfs","g_obj_wait loop: exited.");
3252
3253
    if (lfi != NULL && lfi->fh > 0) {
3254
      rdpfs_release(path, lfi);
3255
    }
3256
3257
    TC_MUTEX_UNLOCK(lmutex);
3258
    free_reqid_fs(reqid);
3259
3260
    if (retstat < 0) {
3261
	retstat = rdpfs_error("rdpfs_access access");
3262
	MDBGLOG("rdpfs","ERROR [rdpfs_access()]: unable to access file");
3263
    }
3264
3265
    if (lfi != NULL) {
3266
      g_free(lfi);
3267
    }
3268
3269
    return retstat;
3270
}
3271
3272
/**
3273
 * Create and open a file
3274
 *
3275
 * If the file does not exist, first create it with the specified
3276
 * mode, and then open it.
3277
 *
3278
 * If this method is not implemented or under Linux kernel
3279
 * versions earlier than 2.6.15, the mknod() and open() methods
3280
 * will be called instead.
3281
 *
3282
 * Introduced in version 2.5
3283
 */
3284
static int rdpfs_create(const char * path, mode_t mode, struct fuse_file_info * fi) {
3285
    RDPFS_DECS;
3286
    int retstat = 0;
3287
    //tbus fd = -1;
3288
    char fpath[PATH_MAX];
3289
    struct stream * s = NULL;
3290
    char buf[512];
3291
    struct stat st;
3292
    //ptrdiff_t idx = 0;
3293
    //tbus objs[1] = { 0x00000000 };
3294
    //size_t num_objs = 0;
3295
    //int timeout = 0;
3296
    struct trans * pcon = (struct trans *)NULL;
3297
    int rdpfs_opcode = 0x00000000;
3298
    ptrdiff_t size = 0x00000000;
3299
    struct _rdpfs_data rdata;
3300
    tc_p lmutex = (tc_p)NULL;
3301
    tc_p lcv = (tc_p)NULL;
3302
    callback * cbdata = NULL;
3303
    uint32_t pflags = 0x00000000;
3304
    uint32_t pshare = 0x00000000;
3305
    uint32_t poptions = 0x00000000;
3306
    uint32_t pattributes = 0x00000000;
3307
    int reqid = -1;
3308
    tbus fhandle = 0;
3309
    int uniqid = 0;
3310
    uint32_t crc32 = 0;
3311
    uint32_t * p_crc32 = (uint32_t *)NULL;
3312
    const uint32_t magic = RDP_PACKET_MAGIC;
3313
    char * p = (char *)NULL;
3314
3315
    TC_MUTEX_LOCK(mutex_fsop);
3316
    get_reqid_fs(&reqid);
3317
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
3318
    TC_MUTEX_LOCK(lmutex);
3319
    TC_MUTEX_UNLOCK(mutex_fsop);
3320
3321
    MDBGLOG("rdpfs","\n\nrdpfs_create(path=\"%s\")\n",path);
3322
3323
    g_memset(&st,0,sizeof(struct stat));
3324
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
3325
    g_memset(buf,0,sizeof(char)*512);
3326
    g_memset(&rdata,0,sizeof(rdpfs_data));
3327
3328
    rdpfs_fullpath(fpath, path);
3329
3330
    get_cv_fs(reqid, &lcv,g_fs);
3331
    cbdata = &(g_reqids[reqid]);
3332
3333
    if ((fi->flags & O_ACCMODE) == O_RDONLY) {
3334
      pflags |= FILE_READ_DATA;
3335
    }
3336
    else if ((fi->flags & O_ACCMODE) == O_WRONLY) {
3337
      pflags |= (FILE_WRITE_DATA | FILE_APPEND_DATA);
3338
    }
3339
    else if ((fi->flags & O_ACCMODE) == O_RDWR) {
3340
      pflags |= (FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA);
3341
    }
3342
    else {
3343
      //pflags |= MAXIMUM_ALLOWED;
3344
      pflags |= (FILE_WRITE_DATA | FILE_APPEND_DATA);
3345
    }
3346
3347
    pflags |= (FILE_WRITE_DATA | FILE_APPEND_DATA);
3348
    pshare |= (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
3349
    poptions |= FILE_NON_DIRECTORY_FILE;
3350
    pattributes |= FILE_ATTRIBUTE_NORMAL;
3351
3352
    rdpfs_opcode = RDPFS_CREATE;
3353
    size = g_strlen(fpath) + 1;
3354
    uniqid = reqid;
3355
3356
    TC_MUTEX_LOCK(mutex_pcon_fs);
3357
    pcon = g_fs->ccon;
3358
    pcon->callback_data = cbdata;
3359
    s = trans_get_out_s(pcon, MAX_STREAM);
3360
    out_uint32_le(s, magic);
3361
    out_uint32_le(s, rdpfs_opcode);
3362
    out_uint32_le(s, size + 16);
3363
    out_uint32_le(s, device_id);
3364
    out_uint32_le(s, fhandle);
3365
    out_uint32_le(s, uniqid);
3366
    p_crc32 = (uint32_t *)s_get_pos(s);
3367
    out_uint32_le(s, crc32);
3368
    p = (char *)s_get_pos(s);
3369
    out_uint32_le(s, pflags);
3370
    out_uint32_le(s, pshare);
3371
    out_uint32_le(s, poptions);
3372
    out_uint32_le(s, pattributes);
3373
    if (size > 0) {
3374
      out_uint8a(s, fpath, size);
3375
    }
3376
    s_mark_end(s);
3377
    size = s->end - s->data;
3378
    if (p_crc32 != NULL) {
3379
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
3380
    }
3381
3382
    MDBGLOG("rdpfs"," ** rdpfs_create(): sending [g_fd = %d]", g_fd);
3383
    trans_force_write(pcon);
3384
    g_memset(s->data,0,MAX_STREAM);
3385
    MDBGLOG("rdpfs","sent.");
3386
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
3387
3388
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
3389
    TC_COND_WAIT(lcv, lmutex);
3390
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
3391
3392
    fhandle = cbdata->FileId;
3393
3394
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
3395
    if (retstat < 0) {
3396
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
3397
      MDBGLOG("rdpfs","ERROR [rdpfs_create()]: \"%s\" (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR)",nterr);
3398
      fhandle = -1;
3399
    }
3400
    else {
3401
      fi->fh = fhandle;
3402
      //log_fi(fi);
3403
    }
3404
3405
    MDBGLOG("rdpfs","rdpfs_create(): done. (fi->fh = %d; fhandle = %d; retstat = %d)",fi->fh,fhandle,retstat);
3406
3407
    TC_MUTEX_UNLOCK(lmutex);
3408
    free_reqid_fs(reqid);
3409
3410
    return retstat;
3411
}
3412
3413
static int rdpfs_create_args(const char * path, mode_t mode, struct fuse_file_info * fi, uint32_t pflags, uint32_t pshare, uint32_t poptions, uint32_t pattributes) {
3414
    RDPFS_DECS;
3415
    int retstat = 0;
3416
    //tbus fd = -1;
3417
    char fpath[PATH_MAX];
3418
    struct stream * s = NULL;
3419
    char buf[512];
3420
    struct stat st;
3421
    //ptrdiff_t idx = 0;
3422
    //tbus objs[1] = { 0x00000000 };
3423
    //size_t num_objs = 0;
3424
    //int timeout = 0;
3425
    struct trans * pcon = (struct trans *)NULL;
3426
    int rdpfs_opcode = 0x00000000;
3427
    ptrdiff_t size = 0x00000000;
3428
    struct _rdpfs_data rdata;
3429
    tc_p lmutex = (tc_p)NULL;
3430
    tc_p lcv = (tc_p)NULL;
3431
    callback * cbdata = NULL;
3432
    int reqid = -1;
3433
    tbus fhandle = 0;
3434
    int uniqid = 0;
3435
    uint32_t crc32 = 0;
3436
    uint32_t * p_crc32 = (uint32_t *)NULL;
3437
    const uint32_t magic = RDP_PACKET_MAGIC;
3438
    char * p = (char *)NULL;
3439
3440
    TC_MUTEX_LOCK(mutex_fsop);
3441
    get_reqid_fs(&reqid);
3442
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
3443
    TC_MUTEX_LOCK(lmutex);
3444
    TC_MUTEX_UNLOCK(mutex_fsop);
3445
3446
    MDBGLOG("rdpfs","\n\nrdpfs_create_args(path=\"%s\"; mode = 0x%8.8x; pflags = 0x%8.8x; pshare = 0x%8.8x; poptions = 0x%8.8x; pattributes = 0x%8.8x)\n",path,mode,pflags,pshare,poptions,pattributes);
3447
3448
    g_memset(&st,0,sizeof(struct stat));
3449
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
3450
    g_memset(buf,0,sizeof(char)*512);
3451
    g_memset(&rdata,0,sizeof(rdpfs_data));
3452
3453
    rdpfs_fullpath(fpath, path);
3454
3455
    get_cv_fs(reqid, &lcv,g_fs);
3456
    cbdata = &(g_reqids[reqid]);
3457
3458
    rdpfs_opcode = RDPFS_CREATE;
3459
    size = g_strlen(fpath) + 1;
3460
    uniqid = reqid;
3461
3462
    TC_MUTEX_LOCK(mutex_pcon_fs);
3463
    pcon = g_fs->ccon;
3464
    pcon->callback_data = cbdata;
3465
    s = trans_get_out_s(pcon, MAX_STREAM);
3466
    out_uint32_le(s, magic);
3467
    out_uint32_le(s, rdpfs_opcode);
3468
    out_uint32_le(s, size + 16);
3469
    out_uint32_le(s, device_id);
3470
    out_uint32_le(s, fhandle);
3471
    out_uint32_le(s, uniqid);
3472
    p_crc32 = (uint32_t *)s_get_pos(s);
3473
    out_uint32_le(s, crc32);
3474
    p = (char *)s_get_pos(s);
3475
    out_uint32_le(s, pflags);
3476
    out_uint32_le(s, pshare);
3477
    out_uint32_le(s, poptions);
3478
    out_uint32_le(s, pattributes);
3479
    if (size > 0) {
3480
      out_uint8a(s, fpath, size);
3481
    }
3482
    s_mark_end(s);
3483
    size = s->end - s->data;
3484
    if (p_crc32 != NULL) {
3485
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
3486
    }
3487
3488
    MDBGLOG("rdpfs"," ** rdpfs_create_args(): sending [g_fd = %d]", g_fd);
3489
    trans_force_write(pcon);
3490
    g_memset(s->data,0,MAX_STREAM);
3491
    MDBGLOG("rdpfs","sent.");
3492
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
3493
3494
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
3495
    TC_COND_WAIT(lcv, lmutex);
3496
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
3497
3498
    fhandle = cbdata->FileId;
3499
3500
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
3501
    if (retstat < 0) {
3502
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
3503
      MDBGLOG("rdpfs","ERROR [rdpfs_create_args()]: \"%s\" (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR)",nterr);
3504
      fhandle = -1;
3505
    }
3506
    else {
3507
      fi->fh = fhandle;
3508
      //log_fi(fi);
3509
    }
3510
3511
    MDBGLOG("rdpfs","rdpfs_create_args(): done. (fi->fh = %d; fhandle = %d; retstat = %d)",fi->fh,fhandle,retstat);
3512
3513
    TC_MUTEX_UNLOCK(lmutex);
3514
    free_reqid_fs(reqid);
3515
3516
    return retstat;
3517
}
3518
3519
/**
3520
 * Change the size of an open file
3521
 *
3522
 * This method is called instead of the truncate() method if the
3523
 * truncation was invoked from an ftruncate() system call.
3524
 *
3525
 * If this method is not implemented or under Linux kernel
3526
 * versions earlier than 2.6.15, the truncate() method will be
3527
 * called instead.
3528
 *
3529
 * Introduced in version 2.5
3530
 */
3531
static int rdpfs_ftruncate(const char * path, off_t offset, struct fuse_file_info * fi) {
3532
    RDPFS_DECS;
3533
    //tbus fd = -1;
3534
    int retstat = 0;
3535
    char fpath[PATH_MAX] = "";
3536
    struct stream * s = NULL;
3537
    //struct stat st;
3538
    //ptrdiff_t idx = 0;
3539
    //tbus objs[1] = { 0x00000000 };
3540
    //size_t num_objs = 0;
3541
    ptrdiff_t fsize = 0;
3542
    struct trans * pcon = (struct trans *)NULL;
3543
    int rdpfs_opcode = 0x00000000;
3544
    int reqid = -1;
3545
    tbus fhandle = 0;
3546
    int uniqid = 0;
3547
    //tbus empty_fi = 0;
3548
    struct fuse_file_info * lfi = NULL;
3549
    tc_p lmutex = (tc_p)NULL;
3550
    tc_p lcv = (tc_p)NULL;
3551
    callback * cbdata = NULL;
3552
    uint64_t toffset = 0x0000000000000000;
3553
    uint32_t crc32 = 0;
3554
    uint32_t * p_crc32 = (uint32_t *)NULL;
3555
    const uint32_t magic = RDP_PACKET_MAGIC;
3556
    char * p = (char *)NULL;
3557
3558
    TC_MUTEX_LOCK(mutex_fsop);
3559
    get_reqid_fs(&reqid);
3560
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
3561
    TC_MUTEX_LOCK(lmutex);
3562
    TC_MUTEX_UNLOCK(mutex_fsop);
3563
3564
    MDBGLOG("rdpfs","\nrdpfs_ftruncate(path=\"%s\", offset=%lld, fi=0x%08x)\n",	path, offset, fi);
3565
3566
    lfi = fi;
3567
    fhandle = lfi->fh;
3568
    toffset = offset;
3569
3570
    cbdata = &(g_reqids[reqid]);
3571
    rdpfs_fullpath(fpath,path);
3572
    rdpfs_opcode = RDPFS_FTRUNCATE;
3573
    fsize = g_strlen(fpath) + 1;
3574
    uniqid = reqid;
3575
3576
    TC_MUTEX_LOCK(mutex_pcon_fs);
3577
    pcon = g_fs->ccon;
3578
    pcon->callback_data = cbdata;
3579
    s = trans_get_out_s(pcon, MAX_STREAM);
3580
    out_uint32_le(s, magic);
3581
    out_uint32_le(s, rdpfs_opcode);
3582
    out_uint32_le(s, fsize + 8);
3583
    out_uint32_le(s, device_id);
3584
    out_uint32_le(s, fhandle);
3585
    out_uint32_le(s, uniqid);
3586
    p_crc32 = (uint32_t *)s_get_pos(s);
3587
    out_uint32_le(s, crc32);
3588
    p = (char *)s_get_pos(s);
3589
    out_uint64_le(s, toffset);
3590
    if (fsize > 0) {
3591
      out_uint8a(s, fpath, fsize);
3592
    }
3593
    s_mark_end(s);
3594
    if (p_crc32 != NULL) {
3595
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
3596
    }
3597
    MDBGLOG("rdpfs"," ** rdpfs_ftruncate (about to send! fsize = %d; fpath = %s)", fsize, fpath);
3598
    fsize = s->end - s->data;
3599
    trans_force_write(pcon);
3600
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
3601
    MDBGLOG("rdpfs","sent.");
3602
3603
    MDBGLOG("rdpfs"," Entering wait loop...");
3604
    get_cv_fs(reqid,&lcv,g_fs);
3605
    TC_COND_WAIT(lcv,lmutex);
3606
    MDBGLOG("rdpfs"," Finished.");
3607
3608
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
3609
    if (retstat < 0) {
3610
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
3611
      MDBGLOG("rdpfs","ERROR [rdpfs_ftruncate()]: \"%s\" (cbdata->IoStatus.Value = 0x%8.8x; retstat = %d)", nterr, cbdata->IoStatus.Value, retstat);
3612
    }
3613
    g_memset(cbdata,0,sizeof(callback));
3614
3615
    TC_MUTEX_UNLOCK(lmutex);
3616
    free_reqid_fs(reqid);
3617
3618
    return retstat;
3619
}
3620
3621
/**
3622
 * Get attributes from an open file
3623
 *
3624
 * This method is called instead of the getattr() method if the
3625
 * file information is available.
3626
 *
3627
 * Currently this is only called after the create() method if that
3628
 * is implemented (see above).  Later it may be called for
3629
 * invocations of fstat() too.
3630
 *
3631
 * Introduced in version 2.5
3632
 */
3633
// Since it's currently only called after rdpfs_create(), and rdpfs_create()
3634
// opens the file, I ought to be able to just use the fd and ignore
3635
// the path...
3636
int rdpfs_fgetattr(const char *path, struct stat *statbuf, struct fuse_file_info *fi) {
3637
    RDPFS_DECS;
3638
    int retstat = 0;
3639
    //tbus fd = -1;
3640
    DIR * dp = (DIR *)NULL;
3641
    char fpath[PATH_MAX];
3642
    struct stream * s = NULL;
3643
    char buf[512];
3644
    struct stat st;
3645
    //ptrdiff_t idx = 0;
3646
    //tbus objs[1] = { 0x00000000 };
3647
    //size_t num_objs = 0;
3648
    //int timeout = 0;
3649
    struct trans * pcon = (struct trans *)NULL;
3650
    int rdpfs_opcode = 0x00000000;
3651
    ptrdiff_t size = 0x00000000;
3652
    int reqid = -1;
3653
    tbus fhandle = 0;
3654
    int uniqid = 0;
3655
    struct fuse_file_info * lfi = NULL;
3656
    tc_p lmutex = (tc_p)NULL;
3657
    tc_p lcv = (tc_p)NULL;
3658
    callback * cbdata = NULL;
3659
    filelist_entry * finfo = NULL;
3660
    uint32_t crc32 = 0;
3661
    uint32_t * p_crc32 = (uint32_t *)NULL;
3662
    const uint32_t magic = RDP_PACKET_MAGIC;
3663
    char * p = (char *)NULL;
3664
3665
    MDBGLOG("rdpfs","\n\nrdpfs_fgetattr(path=\"%s\", statbuf=0x%8.8x)\n",path,statbuf);
3666
3667
    g_memset(&st,0,sizeof(struct stat));
3668
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
3669
    g_memset(buf,0,sizeof(char)*512);
3670
3671
    lfi = fi;
3672
    dp = (DIR *)(uintptr_t) lfi->fh;
3673
    fhandle = (int)(uintptr_t)dp;
3674
3675
    TC_MUTEX_LOCK(mutex_fsop);
3676
    get_reqid_fs(&reqid);
3677
    get_mutex_fs(reqid,(tc_p *)&lmutex,g_fs);
3678
    TC_MUTEX_LOCK(lmutex);
3679
    TC_MUTEX_UNLOCK(mutex_fsop);
3680
3681
    rdpfs_opcode = RDPFS_FGETATTR;
3682
    rdpfs_fullpath(fpath, path);
3683
    size = g_strlen(fpath) + 1;
3684
    uniqid = reqid;
3685
3686
    cbdata = &(g_reqids[reqid]);
3687
    cbdata->userdata = (BYTE *)g_malloc(sizeof(filelist_entry), 1);
3688
    cbdata->uniqid = uniqid;
3689
    cbdata->FileId = fhandle;
3690
3691
    TC_MUTEX_LOCK(mutex_pcon_fs);
3692
    pcon = g_fs->ccon;
3693
    pcon->callback_data = cbdata;
3694
    s = trans_get_out_s(pcon, MAX_STREAM);
3695
    out_uint32_le(s, magic);
3696
    out_uint32_le(s, rdpfs_opcode);
3697
    out_uint32_le(s, size);
3698
    out_uint32_le(s, device_id);
3699
    out_uint32_le(s, fhandle);
3700
    out_uint32_le(s, uniqid);
3701
    p_crc32 = (uint32_t *)s_get_pos(s);
3702
    out_uint32_le(s, crc32);
3703
    p = (char *)s_get_pos(s);
3704
    if (size > 0) {
3705
      out_uint8a(s, fpath, size);
3706
    }
3707
    s_mark_end(s);
3708
    size = s->end - s->data;
3709
    if (p_crc32 != NULL) {
3710
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
3711
    }
3712
3713
    MDBGLOG("rdpfs"," ** rdpfs_fgetattr(): sending [g_fd = %d; pcon->sck = %d; FileId = %d; uniqid = %d]", g_fd, pcon->sck, cbdata->FileId, cbdata->uniqid);
3714
    trans_force_write(pcon);
3715
    g_memset(s->data,0,MAX_STREAM);
3716
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
3717
    MDBGLOG("rdpfs","sent.");
3718
3719
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
3720
    get_cv_fs(reqid,&lcv,g_fs);
3721
    TC_COND_WAIT(lcv, lmutex);
3722
    MDBGLOG("rdpfs","g_obj_wait loop: exited.");
3723
3724
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
3725
    if (retstat < 0) {
3726
	char * nterr = ntstatus_string(cbdata->IoStatus.Value);
3727
	MDBGLOG("rdpfs","ERROR [rdpfs_fgetattr()]: \"%s\" (retstat = %d; cbdata->IoStatus.Value = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
3728
	//g_free(nterr);
3729
	goto end;
3730
    }
3731
3732
    finfo = (filelist_entry *)(cbdata->userdata);
3733
3734
    g_memset(statbuf,0,sizeof(struct stat));
3735
    statbuf->st_dev   = 0x00000801;
3736
    statbuf->st_nlink = finfo->NumberOfLinks;
3737
    statbuf->st_ctime = FileTimeToUnix(finfo->CreationTime);
3738
    statbuf->st_mtime = FileTimeToUnix(finfo->LastWriteTime);
3739
    statbuf->st_atime = FileTimeToUnix(finfo->LastAccessTime);
3740
    statbuf->st_size = finfo->EndOfFile;
3741
    statbuf->st_blocks = finfo->AllocationSize;
3742
    statbuf->st_uid   = 0;
3743
    statbuf->st_gid   = 0;
3744
    if ((finfo->FileAttributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) {
3745
      statbuf->st_mode = 0644;
3746
    }
3747
    else {
3748
      statbuf->st_mode = 0755;
3749
    }
3750
    if ((finfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY || finfo->Directory > 0) {
3751
      /*
3752
       * if the above test is true, then this is a directory:
3753
       */
3754
      statbuf->st_mode |= S_IFDIR;
3755
    }
3756
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && rdpfs_is_blk_file(fpath) > 0) {
3757
      /*
3758
       * if the above test is true, then this is an Interix-type block device file:
3759
       */
3760
      statbuf->st_mode |= S_IFBLK;
3761
      statbuf->st_rdev |= rdpfs_is_blk_file(fpath);
3762
      statbuf->st_size = 0;
3763
      statbuf->st_blocks = 0;
3764
    }
3765
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && rdpfs_is_chr_file(fpath) > 0) {
3766
      /*
3767
       * if the above test is true, then this is an Interix-type character device file:
3768
       */
3769
      statbuf->st_mode |= S_IFCHR;
3770
      statbuf->st_rdev |= rdpfs_is_chr_file(fpath);
3771
      statbuf->st_size = 0;
3772
      statbuf->st_blocks = 0;
3773
    }
3774
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && finfo->EndOfFile > 5 && finfo->EndOfFile < 2048 && rdpfs_is_symlink(fpath) > 0) {
3775
      /*
3776
       * if the above test is true, then this is a "Minshall-French"-type symlink:
3777
       */
3778
      statbuf->st_mode |= S_IFLNK;
3779
    }
3780
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && finfo->EndOfFile == 0) {
3781
      /*
3782
       * if the above test is true, then this is an Interix-type FIFO (named pipe):
3783
       */
3784
      statbuf->st_mode |= S_IFIFO;
3785
      statbuf->st_size = 0;
3786
      statbuf->st_blocks = 0;
3787
    }
3788
    else if ((finfo->FileAttributes & FILE_ATTRIBUTE_SYSTEM) == FILE_ATTRIBUTE_SYSTEM && finfo->EndOfFile == 1) {
3789
      /*
3790
       * if the above test is true, then this is an Interix-type socket:
3791
       */
3792
      statbuf->st_mode |= S_IFSOCK;
3793
      statbuf->st_size = 0;
3794
      statbuf->st_blocks = 0;
3795
    }
3796
    else {
3797
      statbuf->st_mode |= S_IFREG;
3798
    }
3799
3800
  end:
3801
    if (cbdata->userdata != NULL) {
3802
      g_free(cbdata->userdata);
3803
    }
3804
3805
    TC_MUTEX_UNLOCK(lmutex);
3806
    free_reqid_fs(reqid);
3807
3808
    return retstat;
3809
}
3810
3811
/**
3812
 * Ioctl
3813
 *
3814
 * flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
3815
 * 64bit environment.  The size and direction of data is
3816
 * determined by _IOC_*() decoding of cmd.  For _IOC_NONE,
3817
 * data will be NULL, for _IOC_WRITE data is out area, for
3818
 * _IOC_READ in area and if both are set in/out area.  In all
3819
 * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
3820
 *
3821
 * Introduced in version 2.8
3822
 */
3823
/*
3824
int rdpfs_ioctl(const char * path, int cmd, void * arg, struct fuse_file_info * fi, unsigned int flags, void * data) {
3825
    RDPFS_DECS;
3826
    int retstat = 0;
3827
    tbus fd = -1;
3828
    char fpath[PATH_MAX];
3829
    struct stream * s = NULL;
3830
    char buf[512];
3831
    struct stat st;
3832
    struct trans * pcon = (struct trans *)NULL;
3833
    int rdpfs_opcode = 0x00000000;
3834
    ptrdiff_t size = 0x00000000;
3835
    struct _rdpfs_data rdata;
3836
    tc_p lmutex = (tc_p)NULL;
3837
    tc_p lcv = (tc_p)NULL;
3838
    callback * cbdata = NULL;
3839
    int reqid = -1;
3840
    tbus fhandle = 0;
3841
    int uniqid = 0;
3842
    uint32_t crc32 = 0;
3843
    uint32_t * p_crc32 = (uint32_t *)NULL;
3844
    const uint32_t magic = RDP_PACKET_MAGIC;
3845
    char * p = (char *)NULL;
3846
3847
    TC_MUTEX_LOCK(mutex_fsop);
3848
    get_reqid_fs(&reqid);
3849
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
3850
    TC_MUTEX_LOCK(lmutex);
3851
    TC_MUTEX_UNLOCK(mutex_fsop);
3852
3853
    MDBGLOG("rdpfs","\n\nrdpfs_ioctl(path=\"%s\")\n",path);
3854
3855
    g_memset(&st,0,sizeof(struct stat));
3856
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
3857
    g_memset(buf,0,sizeof(char)*512);
3858
    g_memset(&rdata,0,sizeof(rdpfs_data));
3859
3860
    rdpfs_fullpath(fpath, path);
3861
3862
    get_cv_fs(reqid, &lcv,g_fs);
3863
    cbdata = &(g_reqids[reqid]);
3864
3865
    rdpfs_opcode = RDPFS_IOCTL;
3866
    size = g_strlen(fpath) + 1;
3867
    uniqid = reqid;
3868
3869
    TC_MUTEX_LOCK(mutex_pcon_fs);
3870
    pcon = g_fs->ccon;
3871
    pcon->callback_data = cbdata;
3872
    s = trans_get_out_s(pcon, MAX_STREAM);
3873
    out_uint32_le(s, magic);
3874
    out_uint32_le(s, rdpfs_opcode);
3875
    out_uint32_le(s, size + 16);
3876
    out_uint32_le(s, device_id);
3877
    out_uint32_le(s, fhandle);
3878
    out_uint32_le(s, uniqid);
3879
    p_crc32 = (uint32_t *)s_get_pos(s);
3880
    out_uint32_le(s, crc32);
3881
    p = (char *)s_get_pos(s);
3882
3883
    out_uint32_le(s, cmd);
3884
    out_uint32_le(s, 0);
3885
3886
    if (size > 0) {
3887
      out_uint8a(s, fpath, size);
3888
    }
3889
    s_mark_end(s);
3890
    size = s->end - s->data;
3891
3892
    if (p_crc32 != NULL) {
3893
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
3894
    }
3895
3896
    MDBGLOG("rdpfs"," ** rdpfs_ioctl(): sending [g_fd = %d]", g_fd);
3897
    trans_force_write(pcon);
3898
    g_memset(s->data,0,MAX_STREAM);
3899
    MDBGLOG("rdpfs","sent.");
3900
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
3901
3902
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
3903
    TC_COND_WAIT(lcv, lmutex);
3904
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
3905
3906
    fhandle = cbdata->FileId;
3907
3908
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
3909
    if (retstat < 0) {
3910
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
3911
      MDBGLOG("rdpfs","ERROR [rdpfs_ioctl()]: \"%s\" (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR)",nterr);
3912
      fhandle = -1;
3913
    }
3914
    else {
3915
      fi->fh = fhandle;
3916
      //log_fi(fi);
3917
    }
3918
3919
    MDBGLOG("rdpfs","rdpfs_ioctl(): done.");
3920
3921
    TC_MUTEX_UNLOCK(lmutex);
3922
    free_reqid_fs(reqid);
3923
3924
    return retstat;
3925
}
3926
*/
3927
3928
static int rdpfs_fsctl(const char * path, struct fuse_file_info * fi, DWORD cmd, int length, void * data) {
3929
    RDPFS_DECS;
3930
    int retstat = 0;
3931
    //tbus fd = -1;
3932
    char fpath[PATH_MAX];
3933
    struct stream * s = NULL;
3934
    char buf[512];
3935
    struct stat st;
3936
    struct trans * pcon = (struct trans *)NULL;
3937
    int rdpfs_opcode = 0x00000000;
3938
    ptrdiff_t size = 0x00000000;
3939
    struct _rdpfs_data rdata;
3940
    tc_p lmutex = (tc_p)NULL;
3941
    tc_p lcv = (tc_p)NULL;
3942
    callback * cbdata = NULL;
3943
    int reqid = -1;
3944
    tbus fhandle = 0;
3945
    int uniqid = 0;
3946
    FILE_OBJECTID_BUFFER object_id;
3947
    FILE_OBJECTID_BUFFER * oid = &object_id;
3948
    RETRIEVAL_POINTERS_BUFFER lrpn;
3949
    RETRIEVAL_POINTERS_BUFFER * rpn = &lrpn;
3950
    uint32_t crc32 = 0;
3951
    uint32_t * p_crc32 = (uint32_t *)NULL;
3952
    const uint32_t magic = RDP_PACKET_MAGIC;
3953
    char * p = (char *)NULL;
3954
3955
    TC_MUTEX_LOCK(mutex_fsop);
3956
    get_reqid_fs(&reqid);
3957
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
3958
    TC_MUTEX_LOCK(lmutex);
3959
    TC_MUTEX_UNLOCK(mutex_fsop);
3960
3961
    MDBGLOG("rdpfs","\n\nrdpfs_fsctl(path=\"%s\",cmd=\"0x%8.8x\",length=\"%d\")\n",path,cmd,length);
3962
3963
    g_memset(&lrpn,0,sizeof(RETRIEVAL_POINTERS_BUFFER));
3964
    g_memset(&object_id,0,sizeof(FILE_OBJECTID_BUFFER));
3965
    g_memset(&st,0,sizeof(struct stat));
3966
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
3967
    g_memset(buf,0,sizeof(char)*512);
3968
    g_memset(&rdata,0,sizeof(rdpfs_data));
3969
3970
    rdpfs_fullpath(fpath, path);
3971
3972
    get_cv_fs(reqid, &lcv,g_fs);
3973
    cbdata = &(g_reqids[reqid]);
3974
    cbdata->userdata = (void *)oid;
3975
3976
    rdpfs_opcode = RDPFS_FSCTL;
3977
    size = g_strlen(fpath) + 1;
3978
    uniqid = reqid;
3979
    fhandle = fi->fh;
3980
3981
    TC_MUTEX_LOCK(mutex_pcon_fs);
3982
    pcon = g_fs->ccon;
3983
    pcon->callback_data = cbdata;
3984
    s = trans_get_out_s(pcon, MAX_STREAM);
3985
    out_uint32_le(s, magic);
3986
    out_uint32_le(s, rdpfs_opcode);
3987
    out_uint32_le(s, size + 8 + length);
3988
    out_uint32_le(s, device_id);
3989
    out_uint32_le(s, fhandle);
3990
    out_uint32_le(s, uniqid);
3991
    p_crc32 = (uint32_t *)s_get_pos(s);
3992
    out_uint32_le(s, crc32);
3993
    p = (char *)s_get_pos(s);
3994
    out_uint32_le(s, cmd);
3995
    out_uint32_le(s, length);
3996
    if (length > 0) {
3997
      out_uint8a(s, data, length);
3998
    }
3999
    if (size > 0) {
4000
      out_uint8a(s, fpath, size);
4001
    }
4002
    s_mark_end(s);
4003
    size = s->end - s->data;
4004
4005
    if (p_crc32 != NULL) {
4006
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
4007
    }
4008
4009
    MDBGLOG("rdpfs"," ** rdpfs_fsctl(): sending [g_fd = %d]", g_fd);
4010
    trans_force_write(pcon);
4011
    g_memset(s->data,0,MAX_STREAM);
4012
    MDBGLOG("rdpfs","sent.");
4013
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
4014
4015
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
4016
    TC_COND_WAIT(lcv, lmutex);
4017
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
4018
4019
    fhandle = cbdata->FileId;
4020
4021
    if (data != NULL) {
4022
      if ((cmd == FSCTL_CREATE_OR_GET_OBJECT_ID || cmd == FSCTL_GET_OBJECT_ID) && oid != NULL) {
4023
        g_memcpy(data,oid,sizeof(FILE_OBJECTID_BUFFER));
4024
      }
4025
      else if (cmd == FSCTL_GET_RETRIEVAL_POINTERS && rpn != NULL) {
4026
        g_memcpy(data,rpn,sizeof(RETRIEVAL_POINTERS_BUFFER));
4027
      }
4028
    }
4029
4030
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
4031
    if (retstat < 0) {
4032
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
4033
      MDBGLOG("rdpfs","ERROR [rdpfs_fsctl()]: \"%s\" (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR)",nterr);
4034
      fhandle = -1;
4035
    }
4036
    else {
4037
      fi->fh = fhandle;
4038
    }
4039
4040
    MDBGLOG("rdpfs","rdpfs_fsctl(): done.");
4041
4042
    TC_MUTEX_UNLOCK(lmutex);
4043
    free_reqid_fs(reqid);
4044
4045
    return retstat;
4046
}
4047
4048
/**
4049
 * Poll for IO readiness events
4050
 *
4051
 * Note: If ph is non-NULL, the client should notify
4052
 * when IO readiness events occur by calling
4053
 * fuse_notify_poll() with the specified ph.
4054
 *
4055
 * Regardless of the number of times poll with a non-NULL ph
4056
 * is received, single notification is enough to clear all.
4057
 * Notifying more times incurs overhead but doesn't harm
4058
 * correctness.
4059
 *
4060
 * The callee is responsible for destroying ph with
4061
 * fuse_pollhandle_destroy() when no longer in use.
4062
 *
4063
 * Introduced in version 2.8
4064
 */
4065
int rdpfs_poll(const char * path, struct fuse_file_info * fi, struct fuse_pollhandle * ph, unsigned * reventsp) {
4066
    RDPFS_DECS;
4067
    int retstat = 0;
4068
    //tbus fd = -1;
4069
    char fpath[PATH_MAX];
4070
    struct stream * s = NULL;
4071
    char buf[512];
4072
    struct stat st;
4073
    struct trans * pcon = (struct trans *)NULL;
4074
    int rdpfs_opcode = 0x00000000;
4075
    ptrdiff_t size = 0x00000000;
4076
    struct _rdpfs_data rdata;
4077
    tc_p lmutex = (tc_p)NULL;
4078
    tc_p lcv = (tc_p)NULL;
4079
    callback * cbdata = NULL;
4080
    int reqid = -1;
4081
    tbus fhandle = 0;
4082
    int uniqid = 0;
4083
    uint32_t crc32 = 0;
4084
    uint32_t * p_crc32 = (uint32_t *)NULL;
4085
    const uint32_t magic = RDP_PACKET_MAGIC;
4086
    char * p = (char *)NULL;
4087
4088
    TC_MUTEX_LOCK(mutex_fsop);
4089
    get_reqid_fs(&reqid);
4090
    get_mutex_fs(reqid,(tc_p *) &lmutex,g_fs);
4091
    TC_MUTEX_LOCK(lmutex);
4092
    TC_MUTEX_UNLOCK(mutex_fsop);
4093
4094
    MDBGLOG("rdpfs","\n\nrdpfs_poll(path=\"%s\")\n",path);
4095
4096
    g_memset(&st,0,sizeof(struct stat));
4097
    g_memset(fpath,0,sizeof(char)*PATH_MAX);
4098
    g_memset(buf,0,sizeof(char)*512);
4099
    g_memset(&rdata,0,sizeof(rdpfs_data));
4100
4101
    rdpfs_fullpath(fpath, path);
4102
4103
    get_cv_fs(reqid, &lcv,g_fs);
4104
    cbdata = &(g_reqids[reqid]);
4105
4106
    rdpfs_opcode = RDPFS_POLL;
4107
    size = g_strlen(fpath) + 1;
4108
    uniqid = reqid;
4109
4110
    TC_MUTEX_LOCK(mutex_pcon_fs);
4111
    pcon = g_fs->ccon;
4112
    pcon->callback_data = cbdata;
4113
    s = trans_get_out_s(pcon, MAX_STREAM);
4114
    out_uint32_le(s, magic);
4115
    out_uint32_le(s, rdpfs_opcode);
4116
    out_uint32_le(s, size + 16);
4117
    out_uint32_le(s, device_id);
4118
    out_uint32_le(s, fhandle);
4119
    out_uint32_le(s, uniqid);
4120
    p_crc32 = (uint32_t *)s_get_pos(s);
4121
    out_uint32_le(s, crc32);
4122
    p = (char *)s_get_pos(s);
4123
    if (size > 0) {
4124
      out_uint8a(s, fpath, size);
4125
    }
4126
    s_mark_end(s);
4127
    size = s->end - s->data;
4128
4129
    if (p_crc32 != NULL) {
4130
      *p_crc32 = Crc32_ComputeBuf(0, (void *)p, (size_t)(s->end - p));
4131
    }
4132
4133
    MDBGLOG("rdpfs"," ** rdpfs_poll(): sending [g_fd = %d]", g_fd);
4134
    trans_force_write(pcon);
4135
    g_memset(s->data,0,MAX_STREAM);
4136
    MDBGLOG("rdpfs","sent.");
4137
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
4138
4139
    MDBGLOG("rdpfs","entering g_obj_wait loop:");
4140
    TC_COND_WAIT(lcv, lmutex);
4141
    MDBGLOG("rdpfs","exiting g_obj_wait loop.");
4142
4143
    fhandle = cbdata->FileId;
4144
4145
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
4146
    if (retstat < 0) {
4147
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
4148
      MDBGLOG("rdpfs","ERROR [rdpfs_poll()]: \"%s\" (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR)",nterr);
4149
      fhandle = -1;
4150
    }
4151
    else {
4152
      fi->fh = fhandle;
4153
      //log_fi(fi);
4154
    }
4155
4156
    MDBGLOG("rdpfs","rdpfs_poll(): done.");
4157
4158
    TC_MUTEX_UNLOCK(lmutex);
4159
    free_reqid_fs(reqid);
4160
4161
    return retstat;
4162
}
4163
4164
struct fuse_operations rdpfs_oper = {
4165
  //.flag_nullpath_ok = 1,
4166
  .init = rdpfs_init,
4167
  .getattr = rdpfs_getattr,
4168
  .fgetattr = rdpfs_fgetattr,
4169
  .mknod = rdpfs_mknod,
4170
  .mkdir = rdpfs_mkdir,
4171
  .unlink = rdpfs_unlink,
4172
  .rmdir = rdpfs_rmdir,
4173
  .rename = rdpfs_rename,
4174
  .truncate = rdpfs_truncate,
4175
  .ftruncate = rdpfs_ftruncate,
4176
  .utime = rdpfs_utime,
4177
  .open = rdpfs_open,
4178
  .read = rdpfs_read,
4179
  .write = rdpfs_write,
4180
  .statfs = rdpfs_statfs,
4181
  .release = rdpfs_release,
4182
  .opendir = rdpfs_opendir,
4183
  .readdir = rdpfs_readdir,
4184
  .releasedir = rdpfs_releasedir,
4185
  .destroy = rdpfs_destroy,
4186
  .access = rdpfs_access,
4187
  .create = rdpfs_create,
4188
//  .ioctl = rdpfs_ioctl,
4189
//  .poll = rdpfs_poll,
4190
//  .link = rdpfs_link,
4191
  .readlink = rdpfs_readlink,
4192
  .symlink = rdpfs_symlink,
4193
  .chmod = rdpfs_chmod,
4194
  .chown = rdpfs_chown,
4195
//  .flush = rdpfs_flush,
4196
//  .fsync = rdpfs_fsync,
4197
//  .fsyncdir = rdpfs_fsyncdir,
4198
#if defined(__linux__)
4199
//  .listxattr = rdpfs_listxattr,
4200
  .getxattr = rdpfs_getxattr,
4201
//  .setxattr = rdpfs_setxattr,
4202
//  .removexattr = rdpfs_removexattr,
4203
#endif
4204
//  .bmap = rdpfs_bmap,
4205
  .getdir = NULL
4206
};
4207
4208
rdpfs * APP_CC rdpfs_main(int largc, char **iargv, char * mpath) {
4209
    rdpfs * rv = (rdpfs *)NULL;
4210
    ptrdiff_t i = 0;
4211
    struct rdpfs_state * rdpfs_data = (struct rdpfs_state *)NULL;
4212
    int compat = 26;
4213
    struct fuse * fuse = (struct fuse *)NULL;
4214
    char * mountpoint = (char *)NULL;
4215
    int multithreaded = 0;
4216
    tbus fd = -1;
4217
    struct fuse_chan * fc = (struct fuse_chan *)NULL;
4218
    struct fuse_operations * op = (struct fuse_operations *)NULL;
4219
    size_t op_size = 0;
4220
    char ** largv = (char **)NULL;
4221
4222
    MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
4223
4224
    largv = (char **)g_malloc(sizeof(char *) * largc, 1);
4225
    if (iargv != NULL) {
4226
      for (i = 0; i < largc; i++) {
4227
	if (iargv[i] != NULL) {
4228
	  largv[i] = (char *)g_strdup(iargv[i]);
4229
	}
4230
      }
4231
    }
4232
4233
    rv = (rdpfs *)g_malloc(sizeof(rdpfs), 1);
4234
    if (rv == NULL) {
4235
	perror("main g_malloc(): failed to allocate rv as \"rdpfs\"");
4236
	abort();
4237
    }
4238
    rdpfs_data = (struct rdpfs_state *)rv;
4239
    if (rdpfs_data == NULL) {
4240
	perror("main g_malloc(): failed to allocate rdpfs_data as \"struct rdpfs_state\"");
4241
	abort();
4242
    }
4243
4244
    TC_MUTEX_INIT((tc_mut_t *)(&(rv->mut)),NULL);
4245
    TC_MUTEX_INIT((tc_mut_t *)(&(rv->mut_write)),NULL);
4246
4247
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to lock <rv->mut>... [tid = %d; pid = %d]", __func__, g_gettid(), g_getpid());
4248
    TC_MUTEX_LOCK(&(rv->mut));
4249
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> locked <rv->mut>. [tid = %d; pid = %d]", __func__, g_gettid(), g_getpid());
4250
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to lock <rv->mut_write>... [tid = %d; pid = %d]", __func__, g_gettid(), g_getpid());
4251
    TC_MUTEX_LOCK(&(rv->mut_write));
4252
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> locked <rv->mut_write>. [tid = %d; pid = %d]", __func__, g_gettid(), g_getpid());
4253
4254
    rv->magic = RDPFS_CONTEXT_MAGIC;
4255
4256
    // libfuse is able to do most of the command line parsing; all I
4257
    // need to do is to extract the rootdir; this will be the first
4258
    // non-option passed in.  I'm using the GNU non-standard extension
4259
    // and having realpath malloc the space for the path
4260
    // the string.
4261
    for (i = 1; (i < largc) && (largv[i][0] == '-'); i++);
4262
4263
    if (mpath != NULL && g_strlen(mpath) > 0) {
4264
      rdpfs_data->rootdir = realpath(mpath, NULL);
4265
      mountpoint = mpath;
4266
    }
4267
    //multithreaded = 1;
4268
4269
    for (; i < largc; i++) {
4270
      largv[i] = largv[i+1];
4271
    }
4272
    largc--;
4273
4274
    op = &rdpfs_oper;
4275
    op_size = sizeof(struct fuse_operations);
4276
    MDBGLOG("rdpfs","INFO\t[%s()]: largc = %d; largv[0] = %s; largv[1] = %s; op_size = %d; mountpoint = \"%s\".\t[%d, %d]",__func__,largc,largv[0],largv[1],op_size,mountpoint, g_getpid(), g_gettid());
4277
    fuse = rdpfs_setup_common((largc+1), largv, op, op_size, &mountpoint, &multithreaded, (int *)(&fd), &fc, compat, (struct rdpfs_state *)rv);
4278
    if (fuse == NULL) {
4279
      fd = -1;
4280
    }
4281
4282
    rv->fuse = fuse;
4283
    rv->fd = fd;
4284
    rv->ch = fc;
4285
    if (mountpoint != NULL && g_strlen(mountpoint) > 0) {
4286
      rv->mountpoint = (char *)g_strdup(mountpoint);
4287
    }
4288
4289
    rv->initialized = 1;
4290
4291
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to unlock <rv->mut_write>... [tid = %d; pid = %d]", __func__, g_gettid(), g_getpid());
4292
    TC_MUTEX_UNLOCK(&(rv->mut_write));
4293
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to unlock <rv->mut>... [tid = %d; pid = %d]", __func__, g_gettid(), g_getpid());
4294
    TC_MUTEX_UNLOCK(&(rv->mut));
4295
4296
    MDBGLOG("rdpfs","INFO\t[%s()]: done. [%d, %d]",__func__, g_getpid(), g_gettid());
4297
4298
    /*
4299
     *  Return the file descriptor of the newly created
4300
     *  fuse device, so that it can be monitored for incoming
4301
     *  kernel communications (which should be handled
4302
     *  appropriately):
4303
     */
4304
    return rv;
4305
}
4306
4307
4308
/*****************************************************************************/
4309
static struct fuse *rdpfs_setup_common(int largc, char *largv[],
4310
                                      const struct fuse_operations *op,
4311
                                      size_t op_size,
4312
                                      char **mountpoint,
4313
                                      int *multithreaded,
4314
                                      int *fd,
4315
				      struct fuse_chan **ifc,
4316
                                      int compat,
4317
				      struct rdpfs_state * user_data) {
4318
    //struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
4319
    //struct fuse_args args = FUSE_ARGS_INIT(largc, largv);
4320
    struct fuse_args args = FUSE_ARGS_INIT(3, NULL);
4321
    struct fuse * fuse = (struct fuse *)NULL;
4322
    struct fuse_chan * fc = (struct fuse_chan *)NULL;
4323
    int foreground = 0;
4324
    int res = 0;
4325
4326
    MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
4327
4328
    *mountpoint = "/media/tsclient";
4329
    //res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
4330
    res = rdpfs_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
4331
    //res = fuse_parse_cmdline(&args, mountpoint);
4332
    if (res == -1) {
4333
      return NULL;
4334
    }
4335
4336
    if (largv[0] != NULL && g_strlen(largv[0]) > 0) {
4337
      *mountpoint = largv[0];
4338
    }
4339
    if (*mountpoint == NULL || g_strlen(*mountpoint) < 1) {
4340
      *mountpoint = "/media/tsclient";
4341
    }
4342
4343
    MDBGLOG("rdpfs","INFO\t[%s()]: mountpoint = %s; largv[0] = %s; largv[1] = %s; pid = %d; tid = %d", __func__, *mountpoint, largv[0], largv[1], g_getpid(), g_gettid());
4344
4345
    if (!g_directory_exist(*mountpoint)) {
4346
      g_dir_create(*mountpoint, 0777);
4347
    }
4348
4349
    MDBGLOG("rdpfs","INFO\t[%s()]: about to call fuse_mount()... [%d, %d]",__func__,g_getpid(),g_gettid());
4350
    fc = fuse_mount(*mountpoint, &args);
4351
    MDBGLOG("rdpfs","INFO\t[%s()]: fuse_mount() called. [%d, %d]",__func__,g_getpid(),g_gettid());
4352
    *ifc = fc;
4353
4354
    if (fc == NULL) {
4355
      MDBGLOG("rdpfs","ERROR\t[%s()]: failed to mount filesystem",__func__);
4356
      fuse_opt_free_args(&args);
4357
      goto err_free;
4358
    }
4359
    else {
4360
      MDBGLOG("rdpfs","INFO\t[%s()]: about to call fuse_chan_fd()... [%d, %d]",__func__,g_getpid(),g_gettid());
4361
      *fd = fuse_chan_fd(fc);
4362
      MDBGLOG("rdpfs","INFO\t[%s()]: fuse_chan_fd() called. [%d, %d]",__func__,g_getpid(),g_gettid());
4363
    }
4364
    if (*fd < 0) {
4365
      MDBGLOG("rdpfs","ERROR\t[%s()]: failed to obtain file descriptor [%d, %d]",__func__,g_getpid(),g_gettid());
4366
      fuse_opt_free_args(&args);
4367
      goto err_free;
4368
    }
4369
4370
    MDBGLOG("rdpfs","INFO\t[%s()]: fd = %d [%d, %d]",__func__,*fd,g_getpid(),g_gettid());
4371
4372
    fuse = fuse_new(fc, &args, op, op_size, user_data);
4373
    fuse_opt_free_args(&args);
4374
    if (fuse == NULL) {
4375
      MDBGLOG("rdpfs","ERROR\t[%s()]: \"fuse\" is a null pointer; unmounting... [%d, %d]",__func__, g_getpid(), g_gettid());
4376
      goto err_unmount;
4377
    }
4378
4379
    res = fuse_set_signal_handlers(fuse_get_session(fuse));
4380
    if (res == -1) {
4381
      MDBGLOG("rdpfs","ERROR\t[%s()]: fuse_set_signal_handlers() failed [%d, %d]",__func__, g_getpid(), g_gettid());
4382
      goto err_destroy;
4383
    }
4384
4385
    MDBGLOG("rdpfs","INFO\t[%s()]: done. [%d, %d]",__func__, g_getpid(), g_gettid());
4386
4387
    return fuse;
4388
4389
  err_destroy:
4390
    fuse_destroy(fuse);
4391
  err_unmount:
4392
    if (fc != NULL && *mountpoint != NULL) {
4393
      fuse_unmount(*mountpoint, fc);
4394
    }
4395
  err_free:
4396
    free(*mountpoint);
4397
    return NULL;
4398
}
4399
4400
static int fuse_helper_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) {
4401
    struct helper_opts *hopts = data;
4402
4403
    MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
4404
4405
    switch (key) {
4406
    case KEY_HELP:
4407
        //usage(outargs->argv[0]);
4408
        /* fall through */
4409
4410
    case KEY_HELP_NOHEADER:
4411
        //helper_help();
4412
        return fuse_opt_add_arg(outargs, "-h");
4413
4414
    case KEY_VERSION:
4415
        //helper_version();
4416
        return 1;
4417
4418
    case FUSE_OPT_KEY_NONOPT:
4419
        if (!hopts->mountpoint)
4420
            return fuse_opt_add_opt(&hopts->mountpoint, arg);
4421
        else {
4422
            fprintf(stderr, "fuse: invalid argument `%s'\n", arg);
4423
            return -1;
4424
        }
4425
4426
    default:
4427
    case KEY_KEEP:
4428
        return 1;
4429
    }
4430
}
4431
4432
4433
/*****************************************************************************/
4434
static int rdpfs_parse_cmdline(struct fuse_args * args, char ** mountpoint, int * multithreaded, int * foreground) {
4435
    int res = 0;
4436
    struct helper_opts hopts;
4437
4438
    MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
4439
4440
    g_memset(&hopts, 0, sizeof(struct helper_opts));
4441
    if (*mountpoint == NULL) {
4442
      *mountpoint = (char *)g_malloc(sizeof(char) * (g_strlen("/media/tsclient") + 1),1);
4443
      g_snprintf((char *)(*mountpoint),g_strlen("/media/test"),"%s","/media/tsclient");
4444
    }
4445
    res = fuse_opt_parse(args, &hopts, fuse_helper_opts, fuse_helper_opt_proc);
4446
    if (res == -1) {
4447
      g_free(*mountpoint);
4448
      return -1;
4449
    }
4450
4451
    if (!hopts.fsname) {
4452
      if (res == -1) {
4453
        goto err;
4454
      }
4455
    }
4456
    if (mountpoint) {
4457
      *mountpoint = hopts.mountpoint;
4458
    }
4459
    else {
4460
      g_free(hopts.mountpoint);
4461
    }
4462
4463
    if (multithreaded) {
4464
      *multithreaded = !(hopts.singlethread);
4465
    }
4466
    if (foreground) {
4467
      *foreground = hopts.foreground;
4468
    }
4469
    return 0;
4470
4471
 err:
4472
    g_free(hopts.mountpoint);
4473
    return -1;
4474
}
4475
4476
/*****************************************************************************/
4477
inline unsigned long
4478
rdpfs_hash(unsigned char *str) {
4479
  unsigned long hash = 5381;
4480
  int c = 0;
4481
  while ((c = (*str)++)) {
4482
    hash = ((hash << 5) + hash) + c;
4483
  }
4484
  return hash;
4485
}
4486
4487
/*****************************************************************************/
4488
static int APP_CC
4489
rdpfs_cycle(rdpfs * self) {
4490
  int rv = 0;
4491
  int res = 0;
4492
  int done = 0;
4493
  struct fuse_session * se = (struct fuse_session *)NULL;
4494
  struct fuse_chan * ch = (struct fuse_chan *)NULL;
4495
  rdpfs * g_fs = (rdpfs *)NULL;
4496
  int g_fd = -1;
4497
  size_t bufsize = 0;
4498
  char buf[MAX_STREAM];
4499
4500
  MDBGLOG("rdpfs", "INFO\t[%s()]: called (self = %p)\t[%d, %d]", __func__, self, g_getpid(), g_gettid());
4501
4502
  if (self == NULL) {
4503
    MDBGLOG("rdpfs","ERROR\t[%s()]: ** \"self\" is NULL ** [%d, %d]",__func__, g_getpid(), g_gettid());
4504
    rv = -1;
4505
    goto end;
4506
  }
4507
4508
  //TC_MUTEX_LOCK(&(self->mut));
4509
4510
  g_memset((char *)buf,0,sizeof(char)*MAX_STREAM);
4511
  g_fs = self;
4512
  g_fd = self->child_sck;
4513
  se = fuse_get_session(self->fuse);
4514
  ch = fuse_session_next_chan(se, NULL);
4515
  bufsize = fuse_chan_bufsize(ch);
4516
  if (buf == NULL) {
4517
    MDBGLOG("rdpfs","ERROR\t[%s()]: ** failed to allocate read buffer ** [%d, %d]",__func__, g_getpid(), g_gettid());
4518
    rv = -1;
4519
  }
4520
  else {
4521
    while (done == 0) {
4522
      res = fuse_chan_recv(&ch, buf, bufsize);
4523
      if (res == -EINTR) {
4524
	continue;
4525
      }
4526
      else if (res >= 0) {
4527
	done = 1;
4528
      }
4529
      else if (res == -1) {
4530
	break;
4531
      }
4532
      else if (fuse_session_exited(se)) {
4533
	done = 2;
4534
      }
4535
      if (done == 1 && res > 0 && !(fuse_session_exited(se))) {
4536
	fuse_session_process(se, buf, res, ch);
4537
      }
4538
    }
4539
    if (fuse_session_exited(se)) {
4540
      fuse_session_reset(se);
4541
      sleep(200);
4542
    }
4543
  }
4544
  //TC_MUTEX_UNLOCK(&(self->mut));
4545
 end:;
4546
  return rv;
4547
}
4548
4549
4550
rdpfs * APP_CC get_rdpfs_context(void) {
4551
    struct fuse_context * ltmp = (struct fuse_context *)NULL;
4552
    rdpfs * rv = (rdpfs *)NULL;
4553
4554
    MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]",__func__, g_getpid(), g_gettid());
4555
4556
    //TC_MUTEX_LOCK(mutex_fuse);
4557
    ltmp = fuse_get_context();
4558
    if (ltmp == NULL) {
4559
      //TC_MUTEX_UNLOCK(mutex_fuse);
4560
      MDBGLOG("rdpfs", "ERROR\t[%s()]: ltmp is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
4561
      return rv;
4562
    }
4563
    else {
4564
      MDBGLOG("rdpfs", "INFO\t[%s()]: ltmp = %p [%d, %d]", __func__, ltmp, g_getpid(), g_gettid());
4565
      rv = (rdpfs *)(ltmp->private_data);
4566
      MDBGLOG("rdpfs", "INFO\t[%s()]: (...) [%d, %d]", __func__, g_getpid(), g_gettid());
4567
      MDBGLOG("rdpfs", "INFO\t[%s()]: (rv = %p) [%d, %d]", __func__, rv, g_getpid(), g_gettid());
4568
      MDBGLOG("rdpfs", "INFO\t[%s()]: (rv->magic = 0x%8.8x) [%d, %d]", __func__, rv->magic, g_getpid(), g_gettid());
4569
    }
4570
    if (rv != NULL && rv->magic != RDPFS_CONTEXT_MAGIC) {
4571
      const uint32_t tmp = RDPFS_CONTEXT_MAGIC;
4572
      MDBGLOG("rdpfs", "ERROR\t[%s()]: bad magic (rv->magic is \"0x%8.8x\", but should be \"0x%8.8x\") [%d, %d]", __func__, rv->magic, tmp, g_getpid(), g_gettid());
4573
      rv = (rdpfs *)NULL;
4574
    }
4575
4576
    MDBGLOG("rdpfs", "INFO\t[%s()]: done (rv = %p). [%d, %d]", __func__, rv, g_getpid(), g_gettid());
4577
    //TC_MUTEX_UNLOCK(mutex_fuse);
4578
    return rv;
4579
}
4580
4581
rdpfs * APP_CC get_rdpfs_context_by_device_id(int device_id) {
4582
    rdpfs * rv = (rdpfs *)NULL;
4583
4584
    MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
4585
4586
    TC_MUTEX_LOCK(mutex_fuse);
4587
    rv = get_rdpfs_context();
4588
    if (rv == NULL) {
4589
      MDBGLOG("rdpfs", "ERROR\t[%s()]: rv is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
4590
      rv = (rdpfs *)NULL;
4591
    }
4592
    else if (rv != NULL && rv->magic != RDPFS_CONTEXT_MAGIC) {
4593
      const uint32_t tmp = RDPFS_CONTEXT_MAGIC;
4594
      MDBGLOG("rdpfs", "ERROR\t[%s()]: bad magic (rv->magic is \"0x%8.8x\", but should be \"0x%8.8x\") [%d, %d]", __func__, rv->magic, tmp, g_getpid(), g_gettid());
4595
      rv = (rdpfs *)NULL;
4596
    }
4597
    else if (rv != NULL && rv->device_id != device_id) {
4598
      MDBGLOG("rdpfs", "ERROR\t[%s()]: device_id does not match context (rv->device_id is \"0x%8.8x\", but should be \"0x%8.8x\") [%d, %d]", __func__, rv->device_id, device_id, g_getpid(), g_gettid());
4599
      rv = (rdpfs *)NULL;
4600
    }
4601
4602
    MDBGLOG("rdpfs", "INFO\t[%s()]: done (rv = %p). [%d, %d]", __func__, rv, g_getpid(), g_gettid());
4603
    TC_MUTEX_UNLOCK(mutex_fuse);
4604
    return rv;
4605
}
4606
4607
/*****************************************************************************/
4608
/*****		child process-related section				******/
4609
/*****************************************************************************/
4610
4611
4612
/*****************************************************************************/
4613
static size_t APP_CC
4614
parent_data_in(struct trans * trans) {
4615
  struct stream * s = (struct stream *)NULL;
4616
  int rdpfs_opcode = 0;
4617
  int rdpfs_reply = 0;
4618
  ptrdiff_t size = 0;
4619
  int error = 0;
4620
  int fault = 0;
4621
  tbus fhandle = 0;
4622
  int uniqid = 0;
4623
  unsigned char fdone = 0;
4624
  unsigned char fslocked = 0;
4625
  uint32_t device_id = 0;
4626
  uint32_t magic = 0;
4627
  uint32_t crc32 = 0;
4628
  uint32_t calc_crc32 = 0;
4629
  callback * cbdata = (callback *)NULL;
4630
  rdpfs * g_fs = (rdpfs *)NULL;
4631
  int tid = 0;
4632
  unsigned char initted = 0;
4633
  BYTE buf[MAX_STREAM];
4634
4635
  tid = g_gettid();
4636
  MDBGLOG("rdpfs", "INFO\t[%s()]: called [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4637
4638
  g_memset((BYTE *)buf,0,sizeof(buf));
4639
  if (trans == 0) {
4640
    MDBGLOG("rdpfs", "ERROR\t[%s()]: trans is NULL [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4641
    return 0;
4642
  }
4643
4644
  cbdata = (callback *)(trans->callback_data);
4645
  if (cbdata == NULL) {
4646
    MDBGLOG("rdpfs", "ERROR\t[%s()]: cbdata is NULL [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4647
    return 0;
4648
  }
4649
  else if (cbdata->magic != RDPFS_CB_MAGIC) {
4650
    const uint32_t tmp = RDPFS_CB_MAGIC;
4651
    MDBGLOG("rdpfs", "ERROR\t[%s()]: bad magic (cbdata->magic is 0x%8.8x, but should be 0x%8.8x) -- (g_rdpfs = %p; cbdata->fs = %p) [pid = %d; tid = %d]", __func__, cbdata->magic, tmp, g_rdpfs, cbdata->fs, g_getpid(), tid);
4652
    g_fs = g_rdpfs;
4653
  }
4654
  else {
4655
    g_fs = (rdpfs *)(cbdata->fs);
4656
  }
4657
  if (g_fs == NULL) {
4658
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4659
    return 0;
4660
  }
4661
4662
  initted = g_fs->initialized;
4663
  if (initted) {
4664
    int tres = 0;
4665
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to call TC_MUTEX_TRYLOCK(&(g_fs->mut_write))... [tid = %d; pid = %d]", __func__, tid, g_getpid());
4666
    tres = TC_MUTEX_TRYLOCK(&(g_fs->mut_write));
4667
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> tres = %d [tid = %d; pid = %d]", __func__, tres, tid, g_getpid());
4668
    if (tres != 0) {
4669
      MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to lock <g_fs->mut>... [tid = %d; pid = %d]", __func__, tid, g_getpid());
4670
      TC_MUTEX_LOCK(&(g_fs->mut_write));
4671
      MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> locked <g_fs->mut>... [tid = %d; pid = %d]", __func__, tid, g_getpid());
4672
    }
4673
  }
4674
4675
  MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to lock <mutex_pcon_fs>... [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4676
  TC_MUTEX_LOCK(mutex_pcon_fs);
4677
  MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> locked <mutex_pcon_fs>. [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4678
  s = (struct stream *)trans_get_in_s(trans);
4679
  in_uint32_le(s, magic);
4680
  in_uint32_le(s, rdpfs_reply);
4681
  in_uint32_le(s, size);
4682
  in_uint32_le(s, device_id);
4683
  in_uint32_le(s, fhandle);
4684
  in_uint32_le(s, uniqid);
4685
  in_uint32_le(s, crc32);
4686
  if (size > 0) {
4687
    error = trans_force_read(trans, size);
4688
  }
4689
  MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to try to lock <mutex_fs_arr>... [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4690
  fslocked = TC_MUTEX_TRYLOCK(mutex_fs_arr);
4691
  if (fslocked == 0) {
4692
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> locked <mutex_fs_arr>. [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4693
  }
4694
  else {
4695
    MDBGLOG("rdpfs", "WARNING\t[%s()]: <<<>>> unable to lock <mutex_fs_arr>. [pid = %d; tid = %d]", __func__, g_getpid(), tid);
4696
  }
4697
  if (g_fs == NULL && device_id > 0 && g_fs_arr != NULL) {
4698
    ptrdiff_t i = 0;
4699
    //for (i = 0; i < MAX_REQID; i++) {
4700
    for (i = 0; i < g_fs_count; i++) {
4701
      if (g_fs_arr[i] != NULL && g_fs_arr[i]->initialized > 0 && g_fs_arr[i]->device_id == device_id) {
4702
	g_fs = g_fs_arr[i];
4703
      }
4704
    }
4705
  }
4706
  if (fslocked == 0) {
4707
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to unlock <mutex_fs_arr>... [tid = %d; pid = %d]", __func__, tid, g_getpid());
4708
    TC_MUTEX_UNLOCK(mutex_fs_arr);
4709
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> unlocked <mutex_fs_arr>. [tid = %d; pid = %d]", __func__, tid, g_getpid());
4710
  }
4711
  MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to unlock <mutex_pcon_fs>... [tid = %d; pid = %d]", __func__, tid, g_getpid());
4712
  TC_MUTEX_UNLOCK(mutex_pcon_fs);
4713
  MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> unlocked <mutex_pcon_fs>. [tid = %d; pid = %d]", __func__, tid, g_getpid());
4714
  if (error == 0) {
4715
    callback * g_reqids = (callback *)NULL;
4716
    if (size > 0) {
4717
      calc_crc32 = Crc32_ComputeBuf(0, s->p, size);
4718
      MDBGLOG("rdpfs", "INFO\t[%s()]: magic = 0x%8.8x, crc32 = 0x%8.8x, calc_crc32 = 0x%8.8x, g_fs = %p\t[%d, %d]", __func__, magic, crc32, calc_crc32, g_fs, g_getpid(), g_gettid());
4719
    }
4720
    /* the entire message block has been read in, so process it: */
4721
    fault = ((rdpfs_reply & RDPFS_ERROR) == RDPFS_ERROR) ? 1 : 0;
4722
    rdpfs_opcode = rdpfs_reply & (~(RDPFS_REPLY | RDPFS_ERROR));
4723
    MDBGLOG("rdpfs","NOTE\t[%s()]: magic = 0x%8.8x; crc32 = 0x%8.8x; device_id = %d; g_fs->device_id = %d; rdpfs_opcode = 0x%8.8x; rdpfs_reply = 0x%8.8x; fault = %d; uniqid = %d\t[%d, %d]",__func__,magic,crc32,device_id,g_fs->device_id,rdpfs_opcode,rdpfs_reply,fault,uniqid, g_getpid(), g_gettid());
4724
4725
    //g_fs = get_rdpfs_context_by_device_id(device_id);
4726
    if (g_fs == NULL) {
4727
	MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL [tid = %d; pid = %d]", __func__, tid, g_getpid());
4728
	return 0;
4729
    }
4730
    else {
4731
      g_reqids = (callback *)(g_fs->callbacks);
4732
    }
4733
    if (g_reqids == NULL) {
4734
	MDBGLOG("rdpfs", "ERROR\t[%s()]: g_reqids[] is NULL [tid = %d; pid = %d]", __func__, tid, g_getpid());
4735
	return 0;
4736
    }
4737
4738
    if (fault > 0) {
4739
      NTSTATUS iostatus = { .Value = 0x00000000 };
4740
      int reqid = -1;
4741
      callback * cbdata = NULL;
4742
      tc_p lmut = (tc_p)NULL;
4743
      tc_p lcv = (tc_p)NULL;
4744
      char * nterr = (char *)NULL;
4745
4746
      MDBGLOG("rdpfs", "WARNING\t[%s()]: fault [tid = %d; pid = %d]", __func__, tid, g_getpid());
4747
4748
      //TC_MUTEX_LOCK(mutex_fsop);
4749
      in_uint32_le(s, iostatus.Value);
4750
4751
      nterr = ntstatus_string(iostatus.Value);
4752
      MDBGLOG("rdpfs","WARNING\t[%s()]: --> FAULT: \"%s\" (status = 0x%8.8x) [tid = %d; pid = %d]",__func__,nterr,iostatus.Value, tid, g_getpid());
4753
      if (g_reqids == NULL) {
4754
	return -1;
4755
      }
4756
      else {
4757
	cbdata = &(g_reqids[uniqid]);
4758
	reqid = cbdata->opid;
4759
	if (reqid > -1) {
4760
	  get_mutex_fs(reqid,(tc_p *)&lmut,g_fs);
4761
	  //TC_MUTEX_LOCK(lmut);
4762
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4763
	  cbdata->IoStatus.Value = iostatus.Value;
4764
	  get_cv_fs(reqid, &lcv,g_fs);
4765
	  TC_COND_SIGNAL(lcv);
4766
	}
4767
	else {
4768
	  lmut = mutex_fsop;
4769
	}
4770
      }
4771
      //TC_MUTEX_UNLOCK(lmut);
4772
    }
4773
    else switch(rdpfs_opcode) {
4774
      case RDPFS_GETATTR:
4775
      case RDPFS_FGETATTR:
4776
	if (rdpfs_opcode == RDPFS_FGETATTR) {
4777
	  MDBGLOG("rdpfs"," ^^ (RDPFS_FGETATTR)");
4778
	}
4779
	else {
4780
	  MDBGLOG("rdpfs"," ^^ (RDPFS_GETATTR)");
4781
	}
4782
	{
4783
	  DR_DRIVE_QUERY_INFORMATION_RSP iorsp;
4784
	  int reqid = -1;
4785
	  callback * cbdata = NULL;
4786
	  filelist_entry * finfo = NULL;
4787
	  tc_p lmut = (tbus)NULL;
4788
	  tc_p lcv = (tc_p)NULL;
4789
	  //TC_MUTEX_LOCK(mutex_fsop);
4790
	  char * iptr = NULL;
4791
	  char * optr = NULL;
4792
	  ptrdiff_t inum = 0;
4793
	  ptrdiff_t onum = 0;
4794
	  cbdata = &(g_reqids[uniqid]);
4795
	  reqid = cbdata->opid;
4796
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4797
	  TC_MUTEX_LOCK(lmut);
4798
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4799
	  construct_DR_DRIVE_QUERY_INFORMATION_RSP(&iorsp);
4800
	  get_DR_DRIVE_QUERY_INFORMATION_RSP(&iorsp, s);
4801
	  finfo = (filelist_entry *)cbdata->userdata;
4802
	  finfo->CreationTime = iorsp.Buffer.all.BasicInformation.CreationTime;
4803
	  finfo->LastAccessTime = iorsp.Buffer.all.BasicInformation.LastAccessTime;
4804
	  finfo->LastWriteTime = iorsp.Buffer.all.BasicInformation.LastWriteTime;
4805
	  finfo->ChangeTime = iorsp.Buffer.all.BasicInformation.ChangeTime;
4806
	  finfo->FileAttributes = iorsp.Buffer.all.BasicInformation.FileAttributes;
4807
	  finfo->EndOfFile = iorsp.Buffer.all.StandardInformation.EndOfFile;
4808
	  finfo->AllocationSize = iorsp.Buffer.all.StandardInformation.AllocationSize;
4809
	  finfo->NumberOfLinks = iorsp.Buffer.all.StandardInformation.NumberOfLinks;
4810
	  finfo->Directory = iorsp.Buffer.all.StandardInformation.Directory;
4811
	  finfo->DeletePending = iorsp.Buffer.all.StandardInformation.DeletePending;
4812
	  iptr = (char *)iorsp.Buffer.all.NameInformation.FileName;
4813
	  optr = finfo->filename;
4814
	  inum = iorsp.Buffer.all.NameInformation.FileNameLength;
4815
	  onum = sizeof(char) * 512;
4816
	  g_instr(&optr, &onum, &iptr, &inum);
4817
	  MDBGLOG("rdpfs"," --> Length = %d",iorsp.Length);
4818
	  get_cv_fs(reqid, &lcv,g_fs);
4819
	  TC_COND_SIGNAL(lcv);
4820
	  TC_MUTEX_UNLOCK(lmut);
4821
	}
4822
	break;
4823
      case RDPFS_MKNOD:
4824
	MDBGLOG("rdpfs"," ^^ (RDPFS_MKNOD)");
4825
	{
4826
	  int reqid = -1;
4827
	  callback * cbdata = (callback *)NULL;
4828
	  tc_p lmut = (tbus)NULL;
4829
	  tc_p lcv = (tc_p)NULL;
4830
	  //TC_MUTEX_LOCK(mutex_fsop);
4831
	  cbdata = &(g_reqids[uniqid]);
4832
	  reqid = cbdata->opid;
4833
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4834
	  TC_MUTEX_LOCK(lmut);
4835
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4836
	  get_cv_fs(reqid,&lcv,g_fs);
4837
	  TC_COND_SIGNAL(lcv);
4838
	  TC_MUTEX_UNLOCK(lmut);
4839
	}
4840
	break;
4841
      case RDPFS_MKDIR:
4842
	MDBGLOG("rdpfs"," ^^ (RDPFS_MKDIR)");
4843
	{
4844
	  int reqid = -1;
4845
	  callback * cbdata = NULL;
4846
	  DR_DRIVE_CREATE_RSP * iorsp = (DR_DRIVE_CREATE_RSP *)NULL;
4847
	  tc_p lmut = (tbus)NULL;
4848
	  tc_p lcv = (tc_p)NULL;
4849
	  //TC_MUTEX_LOCK(mutex_fsop);
4850
	  cbdata = &(g_reqids[uniqid]);
4851
	  iorsp = (DR_DRIVE_CREATE_RSP *)(cbdata->userdata);
4852
	  reqid = cbdata->opid;
4853
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4854
	  TC_MUTEX_LOCK(lmut);
4855
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4856
	  construct_DR_DRIVE_CREATE_RSP(iorsp);
4857
	  if (size > 0 && size < MAX_STREAM) {
4858
	    get_DR_DRIVE_CREATE_RSP(iorsp, s);
4859
	  }
4860
	  cbdata->FileId = iorsp->DeviceCreateResponse.FileId;
4861
	  MDBGLOG("rdpfs"," --> FileId = %d",cbdata->FileId);
4862
	  get_cv_fs(reqid, &lcv,g_fs);
4863
	  TC_COND_SIGNAL(lcv);
4864
	  TC_MUTEX_UNLOCK(lmut);
4865
	}
4866
	break;
4867
      case RDPFS_UNLINK:
4868
	MDBGLOG("rdpfs"," ^^ (RDPFS_UNLINK)");
4869
	{
4870
	  DR_DRIVE_SET_INFORMATION_RSP iorsp;
4871
	  int reqid = -1;
4872
	  callback * cbdata = (callback *)NULL;
4873
	  tc_p lmut = (tc_p)NULL;
4874
	  tc_p lcv = (tc_p)NULL;
4875
	  //TC_MUTEX_LOCK(mutex_fsop);
4876
	  cbdata = &(g_reqids[uniqid]);
4877
	  reqid = cbdata->opid;
4878
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4879
	  TC_MUTEX_LOCK(lmut);
4880
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4881
	  construct_DR_DRIVE_SET_INFORMATION_RSP(&iorsp);
4882
	  get_DR_DRIVE_SET_INFORMATION_RSP(&iorsp, s);
4883
	  get_cv_fs(reqid,&lcv,g_fs);
4884
	  TC_COND_SIGNAL(lcv);
4885
	  TC_MUTEX_UNLOCK(lmut);
4886
	  MDBGLOG("rdpfs"," ^^ (RDPFS_UNLINK): iorsp.Length = %d",iorsp.Length);
4887
	}
4888
	break;
4889
      case RDPFS_RMDIR:
4890
	MDBGLOG("rdpfs"," ^^ (RDPFS_RMDIR)");
4891
	{
4892
	  DR_DRIVE_SET_INFORMATION_RSP iorsp;
4893
	  int reqid = -1;
4894
	  callback * cbdata = (callback *)NULL;
4895
	  tc_p lmut = (tc_p)NULL;
4896
	  tc_p lcv = (tc_p)NULL;
4897
	  //TC_MUTEX_LOCK(mutex_fsop);
4898
	  cbdata = &(g_reqids[uniqid]);
4899
	  reqid = cbdata->opid;
4900
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4901
	  TC_MUTEX_LOCK(lmut);
4902
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4903
	  construct_DR_DRIVE_SET_INFORMATION_RSP(&iorsp);
4904
	  get_DR_DRIVE_SET_INFORMATION_RSP(&iorsp, s);
4905
	  get_cv_fs(reqid,&lcv,g_fs);
4906
	  TC_COND_SIGNAL(lcv);
4907
	  TC_MUTEX_UNLOCK(lmut);
4908
	  MDBGLOG("rdpfs"," ^^ (RDPFS_RMDIR): iorsp.Length = %d",iorsp.Length);
4909
	}
4910
	break;
4911
      case RDPFS_RENAME:
4912
	MDBGLOG("rdpfs"," ^^ (RDPFS_RENAME)");
4913
	{
4914
	  DR_DRIVE_SET_INFORMATION_RSP iorsp;
4915
	  int reqid = -1;
4916
	  callback * cbdata = (callback *)NULL;
4917
	  tc_p lmut = (tc_p)NULL;
4918
	  tc_p lcv = (tc_p)NULL;
4919
	  //TC_MUTEX_LOCK(mutex_fsop);
4920
	  cbdata = &(g_reqids[uniqid]);
4921
	  reqid = cbdata->opid;
4922
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4923
	  TC_MUTEX_LOCK(lmut);
4924
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4925
	  construct_DR_DRIVE_SET_INFORMATION_RSP(&iorsp);
4926
	  get_DR_DRIVE_SET_INFORMATION_RSP(&iorsp, s);
4927
	  get_cv_fs(reqid,&lcv,g_fs);
4928
	  TC_COND_SIGNAL(lcv);
4929
	  TC_MUTEX_UNLOCK(lmut);
4930
	  MDBGLOG("rdpfs"," ^^ (RDPFS_RENAME): iorsp.Length = %d",iorsp.Length);
4931
	}
4932
	break;
4933
      case RDPFS_LINK:
4934
	MDBGLOG("rdpfs"," ^^ (RDPFS_LINK)");
4935
	{
4936
	  int reqid = -1;
4937
	  callback * cbdata = (callback *)NULL;
4938
	  tc_p lmut = (tc_p)NULL;
4939
	  tc_p lcv = (tc_p)NULL;
4940
	  //TC_MUTEX_LOCK(mutex_fsop);
4941
	  cbdata = &(g_reqids[uniqid]);
4942
	  reqid = cbdata->opid;
4943
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4944
	  TC_MUTEX_LOCK(lmut);
4945
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4946
	  get_cv_fs(reqid,&lcv,g_fs);
4947
	  TC_COND_SIGNAL(lcv);
4948
	  TC_MUTEX_UNLOCK(lmut);
4949
	}
4950
	break;
4951
      case RDPFS_CHMOD:
4952
	MDBGLOG("rdpfs"," ^^ (RDPFS_CHMOD)");
4953
	{
4954
	  int reqid = -1;
4955
	  callback * cbdata = (callback *)NULL;
4956
	  tc_p lmut = (tc_p)NULL;
4957
	  tc_p lcv = (tc_p)NULL;
4958
	  //TC_MUTEX_LOCK(mutex_fsop);
4959
	  cbdata = &(g_reqids[uniqid]);
4960
	  reqid = cbdata->opid;
4961
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4962
	  TC_MUTEX_LOCK(lmut);
4963
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4964
	  get_cv_fs(reqid,&lcv,g_fs);
4965
	  TC_COND_SIGNAL(lcv);
4966
	  TC_MUTEX_UNLOCK(lmut);
4967
	}
4968
	break;
4969
      case RDPFS_CHOWN:
4970
	MDBGLOG("rdpfs"," ^^ (RDPFS_CHOWN)");
4971
	{
4972
	  int reqid = -1;
4973
	  callback * cbdata = (callback *)NULL;
4974
	  tc_p lmut = (tc_p)NULL;
4975
	  tc_p lcv = (tc_p)NULL;
4976
	  //TC_MUTEX_LOCK(mutex_fsop);
4977
	  cbdata = &(g_reqids[uniqid]);
4978
	  reqid = cbdata->opid;
4979
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4980
	  TC_MUTEX_LOCK(lmut);
4981
	  //TC_MUTEX_UNLOCK(mutex_fsop);
4982
	  get_cv_fs(reqid,&lcv,g_fs);
4983
	  TC_COND_SIGNAL(lcv);
4984
	  TC_MUTEX_UNLOCK(lmut);
4985
	}
4986
	break;
4987
      case RDPFS_UTIME:
4988
	MDBGLOG("rdpfs"," ^^ (RDPFS_UTIME)");
4989
	{
4990
	  DR_DRIVE_SET_INFORMATION_RSP iorsp;
4991
	  int reqid = -1;
4992
	  callback * cbdata = (callback *)NULL;
4993
	  tc_p lmut = (tc_p)NULL;
4994
	  tc_p lcv = (tc_p)NULL;
4995
	  //TC_MUTEX_LOCK(mutex_fsop);
4996
	  cbdata = &(g_reqids[uniqid]);
4997
	  reqid = cbdata->opid;
4998
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
4999
	  TC_MUTEX_LOCK(lmut);
5000
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5001
	  construct_DR_DRIVE_SET_INFORMATION_RSP(&iorsp);
5002
	  get_DR_DRIVE_SET_INFORMATION_RSP(&iorsp, s);
5003
	  get_cv_fs(reqid,&lcv,g_fs);
5004
	  TC_COND_SIGNAL(lcv);
5005
	  TC_MUTEX_UNLOCK(lmut);
5006
	  MDBGLOG("rdpfs"," ^^ (RDPFS_UTIME): iorsp.Length = %d",iorsp.Length);
5007
	}
5008
	break;
5009
      case RDPFS_OPENDIR:
5010
	MDBGLOG("rdpfs"," ^^ (RDPFS_OPENDIR)");
5011
	{
5012
	  DR_DRIVE_CREATE_RSP iorsp;
5013
	  int reqid = -1;
5014
	  callback * cbdata = NULL;
5015
	  tc_p lmut = (tc_p)NULL;
5016
	  tc_p lcv = (tc_p)NULL;
5017
	  //TC_MUTEX_LOCK(mutex_fsop);
5018
	  cbdata = &(g_reqids[uniqid]);
5019
	  reqid = cbdata->opid;
5020
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5021
	  TC_MUTEX_LOCK(lmut);
5022
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5023
	  get_cv_fs(reqid, &lcv,g_fs);
5024
	  construct_DR_DRIVE_CREATE_RSP(&iorsp);
5025
	  if (size > 0 && size < MAX_STREAM) {
5026
	    get_DR_DRIVE_CREATE_RSP(&iorsp, s);
5027
	  }
5028
	  cbdata->FileId = iorsp.DeviceCreateResponse.FileId;
5029
	  MDBGLOG("rdpfs"," --> FileId = %d; fhandle = %d",cbdata->FileId,fhandle);
5030
	  {
5031
	    ptrdiff_t tsize = 0;
5032
	    LOCAL_STREAM(v);
5033
	    send_DR_DRIVE_CREATE_RSP(&iorsp, v);
5034
	    s_mark_end(v);
5035
	    tsize = v->end - v->data;
5036
	  }
5037
	  TC_COND_SIGNAL(lcv);
5038
	  TC_MUTEX_UNLOCK(lmut);
5039
	}
5040
	break;
5041
      //case RDP_OPEN:
5042
      case RDPFS_OPEN:
5043
	MDBGLOG("rdpfs"," ^^ (RDPFS_OPEN)");
5044
	{
5045
	  DR_DRIVE_CREATE_RSP iorsp;
5046
	  int reqid = -1;
5047
	  callback * cbdata = NULL;
5048
	  tc_p lmut = (tc_p)NULL;
5049
	  tc_p lcv = (tc_p)NULL;
5050
	  //TC_MUTEX_LOCK(mutex_fsop);
5051
	  cbdata = &(g_reqids[uniqid]);
5052
	  reqid = cbdata->opid;
5053
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5054
	  TC_MUTEX_LOCK(lmut);
5055
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5056
	  get_cv_fs(reqid, &lcv,g_fs);
5057
	  construct_DR_DRIVE_CREATE_RSP(&iorsp);
5058
	  if (size > 0 && size < MAX_STREAM) {
5059
	    get_DR_DRIVE_CREATE_RSP(&iorsp, s);
5060
	  }
5061
	  cbdata->FileId = iorsp.DeviceCreateResponse.FileId;
5062
	  MDBGLOG("rdpfs"," --> FileId = %d; fhandle = %d",cbdata->FileId,fhandle);
5063
	  {
5064
	    ptrdiff_t tsize = 0;
5065
	    LOCAL_STREAM(v);
5066
	    send_DR_DRIVE_CREATE_RSP(&iorsp, v);
5067
	    s_mark_end(v);
5068
	    tsize = v->end - v->data;
5069
	  }
5070
	  TC_COND_SIGNAL(lcv);
5071
	  TC_MUTEX_UNLOCK(lmut);
5072
	}
5073
	break;
5074
      case RDPFS_READDIR:
5075
	MDBGLOG("rdpfs"," ^^ (RDPFS_READDIR)");
5076
	{
5077
	  filelist_entry ** files = (filelist_entry **)NULL;
5078
	  int reqid = -1;
5079
	  FILE_BOTH_DIR_INFORMATION dirinfo;
5080
	  DR_DRIVE_QUERY_DIRECTORY_RSP lrsp;
5081
	  DR_DRIVE_QUERY_DIRECTORY_RSP * rsp = &lrsp;
5082
	  callback * cbdata = (callback *)NULL;
5083
	  filelist * lst = (filelist *)NULL;
5084
	  tc_p lmut = (tc_p)NULL;
5085
	  tc_p lcv = (tc_p)NULL;
5086
	  char * iptr = NULL;
5087
	  char * optr = NULL;
5088
	  ptrdiff_t inum = 0;
5089
	  ptrdiff_t onum = 0;
5090
	  //TC_MUTEX_LOCK(mutex_fsop);
5091
	  cbdata = &(g_reqids[uniqid]);
5092
	  reqid = cbdata->opid;
5093
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5094
	  TC_MUTEX_LOCK(lmut);
5095
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5096
	  construct_DR_DRIVE_QUERY_DIRECTORY_RSP(rsp);
5097
	  lst = (filelist *)(cbdata->userdata);
5098
	  files = lst->files;
5099
	  if (size > 0 && size < MAX_STREAM) {
5100
	    get_DR_DRIVE_QUERY_DIRECTORY_RSP(rsp, s);
5101
	    fdone = (rsp->DeviceIoReply.IoStatus.Value == STATUS_NO_MORE_FILES) ? 1 : 0;
5102
	    if (fdone < 1) {
5103
	      g_memcpy(&dirinfo,&(rsp->Buffer.both),sizeof(FILE_BOTH_DIR_INFORMATION));
5104
	      files[lst->count] = (filelist_entry *)g_malloc(sizeof(filelist_entry), 1);
5105
	      iptr = (char *)dirinfo.FileName;
5106
	      optr = (char *)files[lst->count]->filename;
5107
	      inum = dirinfo.FileNameLength + 2;
5108
	      onum = sizeof(char) * 512;
5109
	      g_instr(&optr, &onum, &iptr, &inum);
5110
	      files[lst->count]->index = lst->count;
5111
	      files[lst->count]->FileAttributes = dirinfo.FileAttributes;
5112
	      files[lst->count]->CreationTime = dirinfo.CreationTime;
5113
	      files[lst->count]->LastAccessTime = dirinfo.LastAccessTime;
5114
	      files[lst->count]->LastWriteTime = dirinfo.LastWriteTime;
5115
	      files[lst->count]->ChangeTime = dirinfo.ChangeTime;
5116
	      files[lst->count]->EndOfFile = dirinfo.EndOfFile;
5117
	      files[lst->count]->AllocationSize = dirinfo.AllocationSize;
5118
	      files[lst->count]->EaSize = dirinfo.EaSize;
5119
	      lst->count++;
5120
	    }
5121
	  }
5122
	  if (fdone > 0) {
5123
	    get_cv_fs(reqid, &lcv,g_fs);
5124
	    TC_COND_SIGNAL(lcv);
5125
	  }
5126
	  TC_MUTEX_UNLOCK(lmut);
5127
	}
5128
	break;
5129
      //case RDP_READ:
5130
      case RDPFS_READ:
5131
	MDBGLOG("rdpfs"," ^^ (RDPFS_READ)");
5132
	{
5133
	  DR_DRIVE_READ_RSP iorsp;
5134
	  int reqid = -1;
5135
	  callback * cbdata = (callback *)NULL;
5136
	  tc_p lmut = (tc_p)NULL;
5137
	  tc_p lcv = (tc_p)NULL;
5138
	  //TC_MUTEX_LOCK(mutex_fsop);
5139
	  cbdata = &(g_reqids[uniqid]);
5140
	  reqid = cbdata->opid;
5141
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5142
	  TC_MUTEX_LOCK(lmut);
5143
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5144
	  construct_DR_READ_RSP(&iorsp);
5145
	  iorsp.ReadData = cbdata->userdata;
5146
	  get_DR_READ_RSP(&iorsp, s);
5147
	  cbdata->length = iorsp.Length;
5148
	  get_cv_fs(reqid,&lcv,g_fs);
5149
	  TC_COND_SIGNAL(lcv);
5150
	  TC_MUTEX_UNLOCK(lmut);
5151
	  MDBGLOG("rdpfs"," ^^ (RDPFS_READ): iorsp.Length = %d; iorsp.ReadData = \"%s\"",iorsp.Length,iorsp.ReadData);
5152
	}
5153
	break;
5154
      //case RDP_WRITE:
5155
      case RDPFS_WRITE:
5156
	MDBGLOG("rdpfs"," ^^ (RDPFS_WRITE)");
5157
	{
5158
	  DR_DRIVE_WRITE_RSP iorsp;
5159
	  int reqid = -1;
5160
	  callback * cbdata = (callback *)NULL;
5161
	  tc_p lmut = (tc_p)NULL;
5162
	  tc_p lcv = (tc_p)NULL;
5163
	  //TC_MUTEX_LOCK(mutex_fsop);
5164
	  cbdata = &(g_reqids[uniqid]);
5165
	  reqid = cbdata->opid;
5166
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5167
	  TC_MUTEX_LOCK(lmut);
5168
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5169
	  construct_DR_WRITE_RSP(&iorsp);
5170
	  get_DR_WRITE_RSP(&iorsp, s);
5171
	  cbdata->length = iorsp.Length;
5172
	  get_cv_fs(reqid,&lcv,g_fs);
5173
	  TC_COND_SIGNAL(lcv);
5174
	  TC_MUTEX_UNLOCK(lmut);
5175
	}
5176
	break;
5177
      case RDPFS_STATFS:
5178
	MDBGLOG("rdpfs"," ^^ (RDPFS_STATFS)");
5179
	{
5180
	  DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP iorsp;
5181
	  int reqid = -1;
5182
	  callback * cbdata = (callback *)NULL;
5183
	  tc_p lmut = (tc_p)NULL;
5184
	  tc_p lcv = (tc_p)NULL;
5185
	  //TC_MUTEX_LOCK(mutex_fsop);
5186
	  cbdata = &(g_reqids[uniqid]);
5187
	  reqid = cbdata->opid;
5188
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5189
	  TC_MUTEX_LOCK(lmut);
5190
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5191
	  construct_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(&iorsp);
5192
	  get_DR_DRIVE_QUERY_VOLUME_INFORMATION_RSP(&iorsp, s);
5193
	  cbdata->length = iorsp.Length;
5194
	  g_memcpy(cbdata->userdata,iorsp.Buffer.bytes,iorsp.Length);
5195
	  get_cv_fs(reqid,&lcv,g_fs);
5196
	  TC_COND_SIGNAL(lcv);
5197
	  TC_MUTEX_UNLOCK(lmut);
5198
	}
5199
	break;
5200
      case RDPFS_FSCTL:
5201
	MDBGLOG("rdpfs"," ^^ (RDPFS_FSCTL)");
5202
	{
5203
	  DR_CONTROL_RSP iorsp;
5204
	  int reqid = -1;
5205
	  callback * cbdata = (callback *)NULL;
5206
	  tc_p lmut = (tc_p)NULL;
5207
	  tc_p lcv = (tc_p)NULL;
5208
	  //TC_MUTEX_LOCK(mutex_fsop);
5209
	  cbdata = &(g_reqids[uniqid]);
5210
	  reqid = cbdata->opid;
5211
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5212
	  TC_MUTEX_LOCK(lmut);
5213
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5214
	  construct_DR_CONTROL_RSP(&iorsp);
5215
	  iorsp.OutputBuffer = cbdata->userdata;
5216
	  get_DR_CONTROL_RSP(&iorsp, s);
5217
	  cbdata->length = iorsp.OutputBufferLength;
5218
	  get_cv_fs(reqid,&lcv,g_fs);
5219
	  TC_COND_SIGNAL(lcv);
5220
	  TC_MUTEX_UNLOCK(lmut);
5221
	  MDBGLOG("rdpfs"," ^^ (RDPFS_FSCTL): iorsp.OutputBufferLength = %d;",iorsp.OutputBufferLength);
5222
	}
5223
	break;
5224
      case RDPFS_FLUSH:
5225
	MDBGLOG("rdpfs"," ^^ (RDPFS_FLUSH)");
5226
	{
5227
	  DR_CONTROL_RSP iorsp;
5228
	  int reqid = -1;
5229
	  callback * cbdata = (callback *)NULL;
5230
	  tc_p lmut = (tc_p)NULL;
5231
	  tc_p lcv = (tc_p)NULL;
5232
	  //TC_MUTEX_LOCK(mutex_fsop);
5233
	  cbdata = &(g_reqids[uniqid]);
5234
	  reqid = cbdata->opid;
5235
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5236
	  TC_MUTEX_LOCK(lmut);
5237
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5238
	  construct_DR_CONTROL_RSP(&iorsp);
5239
	  get_DR_CONTROL_RSP(&iorsp, s);
5240
	  get_cv_fs(reqid,&lcv,g_fs);
5241
	  TC_COND_SIGNAL(lcv);
5242
	  TC_MUTEX_UNLOCK(lmut);
5243
	  MDBGLOG("rdpfs"," ^^ (RDPFS_FLUSH): done");
5244
	}
5245
	break;
5246
      case RDPFS_RELEASE:
5247
	MDBGLOG("rdpfs"," ^^ (RDPFS_RELEASE)");
5248
	{
5249
	  int reqid = -1;
5250
	  callback * cbdata = (callback *)NULL;
5251
	  tc_p lmut = (tc_p)NULL;
5252
	  tc_p lcv = (tc_p)NULL;
5253
	  //TC_MUTEX_LOCK(mutex_fsop);
5254
	  cbdata = &(g_reqids[uniqid]);
5255
	  reqid = cbdata->opid;
5256
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5257
	  TC_MUTEX_LOCK(lmut);
5258
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5259
	  get_cv_fs(reqid,&lcv,g_fs);
5260
	  TC_COND_SIGNAL(lcv);
5261
	  TC_MUTEX_UNLOCK(lmut);
5262
	}
5263
	break;
5264
      case RDPFS_FSYNC:
5265
	MDBGLOG("rdpfs"," ^^ (RDPFS_FSYNC)");
5266
	{
5267
	  int reqid = -1;
5268
	  callback * cbdata = (callback *)NULL;
5269
	  tc_p lmut = (tc_p)NULL;
5270
	  tc_p lcv = (tc_p)NULL;
5271
	  //TC_MUTEX_LOCK(mutex_fsop);
5272
	  cbdata = &(g_reqids[uniqid]);
5273
	  reqid = cbdata->opid;
5274
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5275
	  TC_MUTEX_LOCK(lmut);
5276
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5277
	  get_cv_fs(reqid,&lcv,g_fs);
5278
	  TC_COND_SIGNAL(lcv);
5279
	  TC_MUTEX_UNLOCK(lmut);
5280
	}
5281
	break;
5282
      case RDPFS_RELEASEDIR:
5283
	MDBGLOG("rdpfs"," ^^ (RDPFS_RELEASEDIR)");
5284
	{
5285
	  int reqid = -1;
5286
	  callback * cbdata = (callback *)NULL;
5287
	  tc_p lmut = (tc_p)NULL;
5288
	  tc_p lcv = (tc_p)NULL;
5289
	  //TC_MUTEX_LOCK(mutex_fsop);
5290
	  cbdata = &(g_reqids[uniqid]);
5291
	  reqid = cbdata->opid;
5292
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5293
	  TC_MUTEX_LOCK(lmut);
5294
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5295
	  get_cv_fs(reqid,&lcv,g_fs);
5296
	  TC_COND_SIGNAL(lcv);
5297
	  TC_MUTEX_UNLOCK(lmut);
5298
	}
5299
	break;
5300
      case RDPFS_FSYNCDIR:
5301
	MDBGLOG("rdpfs"," ^^ (RDPFS_FSYNCDIR)");
5302
	{
5303
	  int reqid = -1;
5304
	  callback * cbdata = (callback *)NULL;
5305
	  tc_p lmut = (tc_p)NULL;
5306
	  tc_p lcv = (tc_p)NULL;
5307
	  //TC_MUTEX_LOCK(mutex_fsop);
5308
	  cbdata = &(g_reqids[uniqid]);
5309
	  reqid = cbdata->opid;
5310
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5311
	  TC_MUTEX_LOCK(lmut);
5312
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5313
	  get_cv_fs(reqid,&lcv,g_fs);
5314
	  TC_COND_SIGNAL(lcv);
5315
	  TC_MUTEX_UNLOCK(lmut);
5316
	}
5317
	break;
5318
      //case RDP_INIT:
5319
      case RDPFS_INIT:
5320
	MDBGLOG("rdpfs"," ^^ (RDPFS_INIT)");
5321
	{
5322
	  DR_DRIVE_CREATE_RSP iorsp;
5323
	  int reqid = -1;
5324
	  callback * cbdata = (callback *)NULL;
5325
	  tc_p lmut = (tc_p)NULL;
5326
	  tc_p lcv = (tc_p)NULL;
5327
//	  cbdata = &(g_reqids[uniqid]);
5328
	  cbdata = &(g_fs->callbacks[uniqid]);
5329
	  reqid = cbdata->opid;
5330
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5331
	  if (lmut == 0) {
5332
	    MDBGLOG("rdpfs", "WARNING\t[%s()]: lmut is NULL (%p)!", __func__, lmut);
5333
	  }
5334
	  else {
5335
	    TC_MUTEX_LOCK(lmut);
5336
	  }
5337
	  get_cv_fs(reqid, &lcv, g_fs);
5338
	  g_memset(&iorsp,0,sizeof(DR_DRIVE_CREATE_RSP));
5339
	  construct_DR_DRIVE_CREATE_RSP(&iorsp);
5340
	  if (size > 0 && size < MAX_STREAM) {
5341
	    get_DR_DRIVE_CREATE_RSP(&iorsp, s);
5342
	  }
5343
	  if (trans != NULL && trans->callback_data == NULL) {
5344
	    trans->callback_data = (rdpfs_data *)g_malloc(sizeof(rdpfs_data), 1);
5345
	  }
5346
	  if (trans != NULL) {
5347
	    ((rdpfs_data *)(trans->callback_data))->FileId = iorsp.DeviceCreateResponse.FileId;
5348
	    MDBGLOG("rdpfs"," --> FileId = %d",((rdpfs_data *)(trans->callback_data))->FileId);
5349
	  }
5350
	  TC_COND_SIGNAL(lcv);
5351
	  if (lmut != 0) {
5352
	    TC_MUTEX_UNLOCK(lmut);
5353
	  }
5354
	}
5355
	break;
5356
      case RDPFS_ACCESS:
5357
	MDBGLOG("rdpfs"," ^^ (RDPFS_ACCESS)");
5358
	{
5359
	  int reqid = -1;
5360
	  callback * cbdata = (callback *)NULL;
5361
	  tc_p lmut = (tc_p)NULL;
5362
	  tc_p lcv = (tc_p)NULL;
5363
	  //TC_MUTEX_LOCK(mutex_fsop);
5364
	  cbdata = &(g_reqids[uniqid]);
5365
	  reqid = cbdata->opid;
5366
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5367
	  TC_MUTEX_LOCK(lmut);
5368
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5369
	  get_cv_fs(reqid,&lcv,g_fs);
5370
	  TC_COND_SIGNAL(lcv);
5371
	  TC_MUTEX_UNLOCK(lmut);
5372
	}
5373
	break;
5374
      case RDPFS_CREATE:
5375
	MDBGLOG("rdpfs"," ^^ (RDPFS_CREATE)");
5376
	{
5377
	  DR_DRIVE_CREATE_RSP iorsp;
5378
	  int reqid = -1;
5379
	  callback * cbdata = NULL;
5380
	  tc_p lmut = (tc_p)NULL;
5381
	  tc_p lcv = (tc_p)NULL;
5382
	  //TC_MUTEX_LOCK(mutex_fsop);
5383
	  cbdata = &(g_reqids[uniqid]);
5384
	  reqid = cbdata->opid;
5385
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5386
	  TC_MUTEX_LOCK(lmut);
5387
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5388
	  get_cv_fs(reqid, &lcv,g_fs);
5389
	  construct_DR_DRIVE_CREATE_RSP(&iorsp);
5390
	  if (size > 0 && size < MAX_STREAM) {
5391
	    get_DR_DRIVE_CREATE_RSP(&iorsp, s);
5392
	  }
5393
	  cbdata->FileId = iorsp.DeviceCreateResponse.FileId;
5394
	  MDBGLOG("rdpfs"," --> FileId = %d; fhandle = %d",cbdata->FileId,fhandle);
5395
	  {
5396
	    ptrdiff_t tsize = 0;
5397
	    LOCAL_STREAM(v);
5398
	    send_DR_DRIVE_CREATE_RSP(&iorsp, v);
5399
	    s_mark_end(v);
5400
	    tsize = v->end - v->data;
5401
	  }
5402
	  TC_COND_SIGNAL(lcv);
5403
	  TC_MUTEX_UNLOCK(lmut);
5404
	}
5405
	break;
5406
      case RDPFS_TRUNCATE:
5407
      case RDPFS_FTRUNCATE:
5408
        if (rdpfs_opcode == RDPFS_FTRUNCATE) {
5409
	  MDBGLOG("rdpfs"," ^^ (RDPFS_FTRUNCATE)");
5410
	}
5411
	else {
5412
	  MDBGLOG("rdpfs"," ^^ (RDPFS_TRUNCATE)");
5413
	}
5414
	{
5415
	  DR_CONTROL_RSP iorsp;
5416
	  int reqid = -1;
5417
	  callback * cbdata = (callback *)NULL;
5418
	  tc_p lmut = (tc_p)NULL;
5419
	  tc_p lcv = (tc_p)NULL;
5420
	  //TC_MUTEX_LOCK(mutex_fsop);
5421
	  cbdata = &(g_reqids[uniqid]);
5422
	  reqid = cbdata->opid;
5423
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5424
	  TC_MUTEX_LOCK(lmut);
5425
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5426
5427
	  construct_DR_CONTROL_RSP(&iorsp);
5428
	  get_DR_CONTROL_RSP(&iorsp, s);
5429
5430
	  get_cv_fs(reqid,&lcv,g_fs);
5431
	  TC_COND_SIGNAL(lcv);
5432
	  TC_MUTEX_UNLOCK(lmut);
5433
	  MDBGLOG("rdpfs"," ^^ (RDPFS_FTRUNCATE): done");
5434
	}
5435
	break;
5436
      case RDPFS_GETXATTR:
5437
	MDBGLOG("rdpfs"," ^^ (RDPFS_GETXATTR)");
5438
	{
5439
	  int reqid = -1;
5440
	  callback * cbdata = (callback *)NULL;
5441
	  tc_p lmut = (tc_p)NULL;
5442
	  tc_p lcv = (tc_p)NULL;
5443
	  //TC_MUTEX_LOCK(mutex_fsop);
5444
	  cbdata = &(g_reqids[uniqid]);
5445
	  reqid = cbdata->opid;
5446
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5447
	  TC_MUTEX_LOCK(lmut);
5448
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5449
	  get_cv_fs(reqid,&lcv,g_fs);
5450
	  TC_COND_SIGNAL(lcv);
5451
	  TC_MUTEX_UNLOCK(lmut);
5452
	}
5453
	break;
5454
      case RDPFS_SETXATTR:
5455
	MDBGLOG("rdpfs"," ^^ (RDPFS_SETXATTR)");
5456
	{
5457
	  int reqid = -1;
5458
	  callback * cbdata = (callback *)NULL;
5459
	  tc_p lmut = (tc_p)NULL;
5460
	  tc_p lcv = (tc_p)NULL;
5461
	  //TC_MUTEX_LOCK(mutex_fsop);
5462
	  cbdata = &(g_reqids[uniqid]);
5463
	  reqid = cbdata->opid;
5464
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5465
	  TC_MUTEX_LOCK(lmut);
5466
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5467
	  get_cv_fs(reqid,&lcv,g_fs);
5468
	  TC_COND_SIGNAL(lcv);
5469
	  TC_MUTEX_UNLOCK(lmut);
5470
	}
5471
	break;
5472
      case RDPFS_LISTXATTR:
5473
	MDBGLOG("rdpfs"," ^^ (RDPFS_LISTXATTR)");
5474
	{
5475
	  int reqid = -1;
5476
	  callback * cbdata = (callback *)NULL;
5477
	  tc_p lmut = (tc_p)NULL;
5478
	  tc_p lcv = (tc_p)NULL;
5479
	  //TC_MUTEX_LOCK(mutex_fsop);
5480
	  cbdata = &(g_reqids[uniqid]);
5481
	  reqid = cbdata->opid;
5482
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5483
	  TC_MUTEX_LOCK(lmut);
5484
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5485
	  get_cv_fs(reqid,&lcv,g_fs);
5486
	  TC_COND_SIGNAL(lcv);
5487
	  TC_MUTEX_UNLOCK(lmut);
5488
	}
5489
	break;
5490
      case RDPFS_REMOVEXATTR:
5491
	MDBGLOG("rdpfs"," ^^ (RDPFS_REMOVEXATTR)");
5492
	{
5493
	  int reqid = -1;
5494
	  callback * cbdata = (callback *)NULL;
5495
	  tc_p lmut = (tc_p)NULL;
5496
	  tc_p lcv = (tc_p)NULL;
5497
	  //TC_MUTEX_LOCK(mutex_fsop);
5498
	  cbdata = &(g_reqids[uniqid]);
5499
	  reqid = cbdata->opid;
5500
	  get_mutex_fs(reqid,(tc_p *) &lmut,g_fs);
5501
	  TC_MUTEX_LOCK(lmut);
5502
	  //TC_MUTEX_UNLOCK(mutex_fsop);
5503
	  get_cv_fs(reqid,&lcv,g_fs);
5504
	  TC_COND_SIGNAL(lcv);
5505
	  TC_MUTEX_UNLOCK(lmut);
5506
	}
5507
	break;
5508
      case RDPFS_DESTROY:
5509
	MDBGLOG("rdpfs"," ^^ (RDPFS_DESTROY)");
5510
	exit(0);
5511
	break;
5512
      case RDPFS_END:
5513
	MDBGLOG("rdpfs"," ^^ (RDPFS_END)");
5514
	exit(0);
5515
	break;
5516
      case RDPFS_ERROR:
5517
	MDBGLOG("rdpfs"," ^^ (RDPFS_ERROR)");
5518
	exit(0);
5519
	break;
5520
    }
5521
  }
5522
  //TC_MUTEX_UNLOCK(mutex_pcon_fs);
5523
  if (initted) {
5524
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> about to unlock <g_fs->mut_write>... [tid = %d; pid = %d]", __func__, tid, g_getpid());
5525
    TC_MUTEX_UNLOCK(&(g_fs->mut_write));
5526
    MDBGLOG("rdpfs", "INFO\t[%s()]: <<<>>> unlocked <g_fs->mut_write>... [tid = %d; pid = %d]", __func__, tid, g_getpid());
5527
  }
5528
  MDBGLOG("rdpfs", "INFO\t[%s()]: done. [%d, %d]", __func__, g_getpid(), g_gettid());
5529
  return error;
5530
}
5531
5532
typedef struct _handle_filesystem_loop_args {
5533
	rdpfs *			fs;
5534
	struct trans *		pcon;
5535
	tbus			objs[2];
5536
	int			num_objs;
5537
	int			timeout;
5538
	int			check_parent;
5539
	int			check_fuse;
5540
} handle_filesystem_loop_args;
5541
5542
static void * APP_CC
5543
loop_parent_fs(void * inargs) {
5544
  void * rv = (void *)NULL;
5545
  handle_filesystem_loop_args * largs = (handle_filesystem_loop_args *)inargs;
5546
  struct trans * pcon = largs->pcon;
5547
  tbus * objs = (tbus *)(largs->objs);
5548
  size_t num_objs = largs->num_objs;
5549
  int timeout = largs->timeout;
5550
  int check_parent = largs->check_parent;
5551
  int tpid = 0;
5552
  tpid = g_gettid();
5553
  MDBGLOG("rdpfs", "INFO\t[%s()]: spawned thread (inargs = %p)... [pid = %d, tid = %d]", __func__, inargs, g_getpid(), tpid);
5554
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_parent > 0) {
5555
    MDBGLOG("rdpfs","INFO\t[%s()]: num_objs = %d, objs = %p",__func__,num_objs,objs);
5556
    /* handle any inbound communication from the parent process: */
5557
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
5558
      if ((check_parent > 0) && g_is_wait_obj_set(objs[0])) {
5559
	TC_MUTEX_LOCK(mutex_parent_fs);
5560
	if (trans_check_wait_objs(pcon) != 0) {
5561
	  MDBGLOG("rdpfs","ERROR [loop_parent_fs()]: ");
5562
	  //rv = -1;
5563
	  break;
5564
	}
5565
	TC_MUTEX_UNLOCK(mutex_parent_fs);
5566
      }
5567
    }
5568
  }
5569
  MDBGLOG("rdpfs", "INFO\t[%s()]: exiting thread (%d)", __func__, tpid);
5570
  TC_THREAD_EXIT(NULL);
5571
  return rv;
5572
}
5573
5574
static void * APP_CC
5575
loop_fuse(void * inargs) {
5576
  void * rv = (void *)NULL;
5577
  handle_filesystem_loop_args * largs = (handle_filesystem_loop_args *)inargs;
5578
  rdpfs * fs = largs->fs;
5579
  tbus * objs = (tbus *)(largs->objs);
5580
  size_t num_objs = largs->num_objs;
5581
  int timeout = largs->timeout;
5582
  int check_fuse = largs->check_fuse;
5583
  int tpid = 0;
5584
  tpid = g_gettid();
5585
  MDBGLOG("rdpfs", "INFO\t[%s()]: spawned thread (%d)...", __func__, tpid);
5586
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_fuse > 0) {
5587
    /* handle communication from libfuse: */
5588
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
5589
      if ((check_fuse > 0) && ((num_objs == 2 && g_is_wait_obj_set(objs[1])) || (num_objs == 1 && g_is_wait_obj_set(objs[0])))) {
5590
	TC_MUTEX_LOCK(mutex_fuse);
5591
	rdpfs_cycle(fs);
5592
	TC_MUTEX_UNLOCK(mutex_fuse);
5593
      }
5594
    }
5595
  }
5596
  MDBGLOG("rdpfs", "INFO\t[%s()]: exiting thread (%d)", __func__, tpid);
5597
  TC_THREAD_EXIT(NULL);
5598
  return rv;
5599
}
5600
5601
/*****************************************************************************/
5602
int APP_CC handle_filesystem(tbus sck, rdpfs * fs, rdpfs ** fs_arr, tc_p imut) {
5603
  int rv = 0;
5604
  struct trans * pcon = (struct trans *)NULL;
5605
  tbus objs[2] = { -1, -1 };
5606
  size_t num_objs = 0;
5607
  int timeout = 0;
5608
  int check_parent = 0;
5609
  int check_fuse = 0;
5610
  handle_filesystem_loop_args largs;
5611
  tc_thread_t thread_parent;
5612
  tc_thread_t thread_fuse;
5613
  rdpfs * g_fs = (rdpfs *)NULL;
5614
5615
  MDBGLOG("rdpfs", "INFO\t[%s()]: called (sck = %d)  [%d, %d]", __func__, sck, g_getpid(), g_gettid());
5616
  g_memset(&largs,0,sizeof(handle_filesystem_loop_args));
5617
  g_memset(&thread_parent,0,sizeof(tbus));
5618
  g_memset(&thread_fuse,0,sizeof(tbus));
5619
  g_fs = fs;
5620
  g_fs_arr = fs_arr;
5621
  mutex_fs_arr = imut;
5622
5623
  mutex_pcon_fs = &(g_fs->g_mutex_pcon_fs);
5624
  mutex_fs = &(g_fs->g_mutex_fs);
5625
  mutex_fsop = &(g_fs->g_mutex_fsop);
5626
  mutex_parent_fs = &(g_fs->g_mutex_parent_fs);
5627
  mutex_fuse = &(g_fs->g_mutex_fuse);
5628
  mutex_reqid_fs = &(g_fs->g_mutex_reqid_fs);
5629
  mutex_getattr = &(g_fs->g_mutex_getattr);
5630
  cv_readdir = &(g_fs->g_cv_readdir);
5631
5632
  {
5633
    tc_t mattr;
5634
    tc_t cattr;
5635
    tc_p pmattr = (tc_p)&mattr;
5636
    tc_p pcattr = (tc_p)&cattr;
5637
    g_memset(pmattr,0,sizeof(tc_t));
5638
    g_memset(pcattr,0,sizeof(tc_t));
5639
    TC_MUTATTR_INIT(pmattr);
5640
    TC_MUTATTR_SETPSHARED(pmattr, TC_PROCESS_SHARED);
5641
    //TC_MUTATTR_SETPSHARED(pmattr, TC_PROCESS_PRIVATE);
5642
    TC_MUTATTR_SETTYPE(pmattr, TC_MUTEX_ERRORCHECK);
5643
    TC_MUTEX_INIT(mutex_pcon_fs,pmattr);
5644
    TC_MUTEX_INIT(mutex_fs,pmattr);
5645
    TC_MUTEX_INIT(mutex_fsop,pmattr);
5646
    TC_MUTEX_INIT(mutex_parent_fs,pmattr);
5647
    TC_MUTEX_INIT(mutex_fuse,pmattr);
5648
    TC_MUTEX_INIT(mutex_reqid_fs,pmattr);
5649
    TC_MUTEX_INIT(mutex_getattr,pmattr);
5650
5651
    TC_CONDATTR_INIT(pcattr);
5652
    TC_CONDATTR_SETPSHARED(pmattr, TC_PROCESS_SHARED);
5653
    //TC_CONDATTR_SETPSHARED(pmattr, TC_PROCESS_PRIVATE);
5654
    TC_COND_CREATE(cv_readdir,pcattr);
5655
  }
5656
5657
  TC_MUTEX_LOCK(mutex_pcon_fs);
5658
  TC_MUTEX_LOCK(mutex_fs);
5659
5660
  init_reqids_fs(fs);
5661
5662
    /* set up pcon as a transmission channel to the parent */
5663
5664
  pcon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
5665
5666
  pcon->trans_data_in = &parent_data_in;
5667
  pcon->header_size = 28;
5668
//  pcon->header_size = 24;
5669
//  pcon->header_size = 16;
5670
  rv = trans_attach(pcon, sck);
5671
5672
  pcon->sck = sck;
5673
  //pcon->callback_data = fs;
5674
  fs->ccon = pcon;
5675
5676
  TC_MUTEX_UNLOCK(mutex_pcon_fs);
5677
  TC_MUTEX_UNLOCK(mutex_fs);
5678
5679
  g_memset(g_fattr_cache, 0, sizeof(g_fattr_cache));
5680
5681
  if (rv > -1) {
5682
5683
    TC_MUTEX_LOCK(mutex_pcon_fs);
5684
    TC_MUTEX_LOCK(mutex_fs);
5685
5686
    /* add pcon to the set of monitored channels */
5687
    if (pcon != NULL && pcon->sck > 0) {
5688
      objs[num_objs] = pcon->sck;
5689
      num_objs++;
5690
      check_parent = 1;
5691
    }
5692
5693
    /* add the appropriate /dev/fuse file descriptor to the set of monitored channels */
5694
    if (fs->fd > 0) {
5695
      objs[num_objs] = fs->fd;
5696
      num_objs++;
5697
      check_fuse = 1;
5698
    }
5699
5700
    TC_MUTEX_UNLOCK(mutex_pcon_fs);
5701
    TC_MUTEX_UNLOCK(mutex_fs);
5702
5703
    /* monitor the above channels for input and respond appropriately */
5704
    if (num_objs > 0 && objs[0] > -1) {
5705
5706
      TC_MUTEX_LOCK(mutex_pcon_fs);
5707
      TC_MUTEX_LOCK(mutex_fs);
5708
5709
      largs.fs = fs;
5710
      largs.pcon = pcon;
5711
      largs.objs[0] = objs[0];
5712
      largs.objs[1] = objs[1];
5713
      largs.num_objs = num_objs;
5714
      largs.timeout = timeout;
5715
      largs.check_parent = check_parent;
5716
      largs.check_fuse = check_fuse;
5717
5718
      TC_MUTEX_UNLOCK(mutex_pcon_fs);
5719
      TC_MUTEX_UNLOCK(mutex_fs);
5720
5721
      if (objs != NULL && num_objs > 0 && (check_parent > 0 || check_fuse > 0)) {
5722
	tc_t lattr;	// (tc_threadattr_t)lattr
5723
	g_memset(&lattr,0,sizeof(tc_t));
5724
	tc_threadattr_init(&lattr);
5725
	tc_threadattr_setdetachstate(&lattr, TC_CREATE_JOINABLE);
5726
	tc_thread_init_full(&thread_parent,(const tc_threadattr_t *)&lattr,&loop_parent_fs,&largs);
5727
	tc_thread_init_full(&thread_fuse,(const tc_threadattr_t *)&lattr,&loop_fuse,&largs);
5728
5729
	TC_THREAD_JOIN(thread_parent,NULL);
5730
	TC_THREAD_JOIN(thread_fuse,NULL);
5731
      }
5732
    }
5733
  }
5734
5735
  MDBGLOG("rdpfs","INFO\t[%s()]: done.",__func__);
5736
  return rv;
5737
}
5738
5739
static int APP_CC get_reqid_fs(int * inarg) {
5740
  int rv = 0;
5741
5742
  MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
5743
5744
  if (inarg == NULL) {
5745
    rv = -1;
5746
  }
5747
  else {
5748
    rdpfs * g_fs = (rdpfs *)NULL;
5749
    callback * g_reqids = (callback *)NULL;
5750
5751
    *inarg = -1;
5752
5753
    g_fs = get_rdpfs_context();
5754
    MDBGLOG("rdpfs", "INFO\t[%s()]: g_fs = %p [%d, %d]", __func__, g_fs, g_getpid(), g_gettid());
5755
    MDBGLOG("rdpfs", "INFO\t[%s()]: g_fs->device_id = %d [%d, %d]", __func__, g_fs->device_id, g_getpid(), g_gettid());
5756
    if (g_fs == NULL) {
5757
	MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5758
	return -1;
5759
    }
5760
    else {
5761
      g_reqids = (callback *)(g_fs->callbacks);
5762
    }
5763
    if (g_reqids == NULL) {
5764
	MDBGLOG("rdpfs", "ERROR\t[%s()]: g_reqids[] is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5765
	return -1;
5766
    }
5767
5768
    for (rv = 0; rv < MAX_REQID; rv++) {
5769
      MDBGLOG("rdpfs", "INFO\t[%s()]: (iteration %d) [%d, %d]", __func__, rv, g_getpid(), g_gettid());
5770
      if (g_reqids[rv].opid == -1) {
5771
	tc_p tptr_cv;
5772
	tc_p tptr_mut;
5773
	*inarg = rv;
5774
	g_reqids[rv].opid = rv;
5775
5776
	g_reqids[rv].magic = RDPFS_CB_MAGIC;
5777
	g_reqids[rv].fs = g_fs;
5778
	g_reqids[rv].device_id = g_fs->device_id;
5779
5780
	tptr_cv = &(g_reqids[rv].cv);
5781
	tptr_mut = &(g_reqids[rv].mutex);
5782
	TC_MUTEX_INIT(tptr_mut,NULL);
5783
	TC_COND_CREATE(tptr_cv,NULL);
5784
	break;
5785
      }
5786
    }
5787
  }
5788
  MDBGLOG("rdpfs", "INFO\t[%s()]: done. [%d, %d]", __func__, g_getpid(), g_gettid());
5789
  return rv;
5790
}
5791
5792
static int APP_CC free_reqid_fs(int inarg) {
5793
  int rv = 0;
5794
  rdpfs * g_fs = (rdpfs *)NULL;
5795
  callback * g_reqids = (callback *)NULL;
5796
5797
  MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
5798
5799
  g_fs = get_rdpfs_context();
5800
  if (g_fs == NULL) {
5801
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5802
    return -1;
5803
  }
5804
  else {
5805
    g_reqids = (callback *)(&(g_fs->callbacks));
5806
  }
5807
  if (g_reqids == NULL) {
5808
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_reqids[] is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5809
    return -1;
5810
  }
5811
5812
  if (inarg < 0 || inarg > MAX_REQID) {
5813
    rv = -1;
5814
  }
5815
  else if (g_reqids[inarg].opid > -1 && g_reqids[inarg].opid <= MAX_REQID) {
5816
    TC_MUTEX_DEINIT(&(g_reqids[inarg].mutex));
5817
    TC_COND_DEINIT(&(g_reqids[inarg].cv));
5818
    g_memset(&(g_reqids[inarg]),0,sizeof(callback));
5819
    g_reqids[inarg].opid = -1;
5820
  }
5821
  return rv;
5822
}
5823
5824
5825
static int APP_CC init_reqids_fs(rdpfs * g_fs) {
5826
  int rv = 0;
5827
  ptrdiff_t i = 0;
5828
  callback * g_reqids = (callback *)NULL;
5829
5830
  MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
5831
5832
  if (g_fs == NULL) {
5833
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5834
    return -1;
5835
  }
5836
  else {
5837
    g_reqids = (callback *)(&(g_fs->callbacks));
5838
  }
5839
  if (g_reqids == NULL) {
5840
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_reqids[] is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5841
    return -1;
5842
  }
5843
5844
  MDBGLOG("rdpfs", "INFO\t[%s()]: LOCKING <mutex_reqid_fs> [%d, %d]", __func__, g_getpid(), g_gettid());
5845
  TC_MUTEX_LOCK(mutex_reqid_fs);
5846
  MDBGLOG("rdpfs", "INFO\t[%s()]: LOCKED <mutex_reqid_fs> [%d, %d]", __func__, g_getpid(), g_gettid());
5847
  g_memset((callback *)g_reqids,0,sizeof(callback)*MAX_REQID);
5848
  for (i = 0; i < MAX_REQID; i++) {
5849
    tc_p tptr_mut;
5850
    tc_p tptr_cv;
5851
    g_reqids[i].opid = -1;
5852
    g_reqids[i].magic = RDPFS_CB_MAGIC;
5853
    g_reqids[i].fs = g_fs;
5854
    g_reqids[i].device_id = g_fs->device_id;
5855
5856
    tptr_cv = &(g_reqids[i].cv);
5857
    tptr_mut = &(g_reqids[i].mutex);
5858
  }
5859
  MDBGLOG("rdpfs", "INFO\t[%s()]: UNLOCKING <mutex_reqid_fs> [%d, %d]", __func__, g_getpid(), g_gettid());
5860
  TC_MUTEX_UNLOCK(mutex_reqid_fs);
5861
  MDBGLOG("rdpfs", "INFO\t[%s()]: UNLOCKED <mutex_reqid_fs> [%d, %d]", __func__, g_getpid(), g_gettid());
5862
  MDBGLOG("rdpfs","INFO\t[%s()]: done. [%d, %d]",__func__, g_getpid(), g_gettid());
5863
  return rv;
5864
}
5865
5866
static int APP_CC get_mutex_fs(int reqid, tc_p * inarg, rdpfs * g_fs) {
5867
  int rv = 0;
5868
  callback * g_reqids = (callback *)NULL;
5869
5870
  MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
5871
5872
  if (g_fs == NULL) {
5873
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL", __func__);
5874
    return -1;
5875
  }
5876
  else {
5877
    g_reqids = (callback *)(g_fs->callbacks);
5878
  }
5879
  if (g_reqids == NULL) {
5880
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_reqids[] is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5881
    return -1;
5882
  }
5883
5884
  if (reqid >= 0 && reqid < MAX_REQID) {
5885
    *inarg = (tc_p)(&(g_reqids[reqid].mutex));
5886
  }
5887
  else {
5888
    rv = -1;
5889
  }
5890
  return rv;
5891
}
5892
5893
static int APP_CC get_cv_fs(int reqid, tc_p * inarg, rdpfs * g_fs) {
5894
  int rv = 0;
5895
  callback * g_reqids = (callback *)NULL;
5896
5897
  MDBGLOG("rdpfs", "INFO\t[%s()]: called (reqid = %d) [%d, %d]", __func__, reqid, g_getpid(), g_gettid());
5898
5899
  if (inarg == NULL) {
5900
    MDBGLOG("rdpfs", "ERROR\t[%s()]: inarg is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5901
    return -1;
5902
  }
5903
5904
  if (g_fs == NULL) {
5905
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5906
    return -1;
5907
  }
5908
  else {
5909
    g_reqids = (callback *)(g_fs->callbacks);
5910
  }
5911
  if (g_reqids == NULL) {
5912
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_reqids[] is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5913
    return -1;
5914
  }
5915
5916
  if (reqid >= 0 && reqid < MAX_REQID) {
5917
    *inarg = (tc_p)(&(g_reqids[reqid].cv));
5918
  }
5919
  else {
5920
    rv = -1;
5921
  }
5922
  MDBGLOG("rdpfs", "INFO\t[%s()]: done (rv = %d). [%d, %d]", __func__, rv, g_getpid(), g_gettid());
5923
  return rv;
5924
}
5925
5926
static int APP_CC get_cbdata_fs(int reqid, callback ** inarg) {
5927
  int rv = 0;
5928
  rdpfs * g_fs = (rdpfs *)NULL;
5929
  callback * g_reqids = (callback *)NULL;
5930
5931
  MDBGLOG("rdpfs", "INFO\t[%s()]: called [%d, %d]", __func__, g_getpid(), g_gettid());
5932
5933
  if (inarg == NULL) {
5934
    MDBGLOG("rdpfs", "ERROR\t[%s()]: inarg is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5935
    return -1;
5936
  }
5937
5938
  g_fs = get_rdpfs_context();
5939
  if (g_fs == NULL) {
5940
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_fs is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5941
    return -1;
5942
  }
5943
  else {
5944
    g_reqids = (callback *)(g_fs->callbacks);
5945
  }
5946
  if (g_reqids == NULL) {
5947
    MDBGLOG("rdpfs", "ERROR\t[%s()]: g_reqids[] is NULL [%d, %d]", __func__, g_getpid(), g_gettid());
5948
    return -1;
5949
  }
5950
  else if (reqid >= 0 && reqid < MAX_REQID) {
5951
    *inarg = &(g_reqids[reqid]);
5952
  }
5953
  else {
5954
    rv = -1;
5955
  }
5956
  MDBGLOG("rdpfs", "INFO\t[%s()]: done (rv = %d). [%d, %d]", __func__, rv, g_getpid(), g_gettid());
5957
  return rv;
5958
}
5959
5960
5961
static int APP_CC ntstatus_to_errcode(DWORD ntstat) {
5962
  int retstat = 0;
5963
5964
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
5965
5966
  switch (ntstat) {
5967
	case 0:
5968
	  retstat = 0;
5969
	  break;
5970
	case STATUS_ACCESS_DENIED:
5971
	case STATUS_ACCESS_VIOLATION:
5972
	case STATUS_NETWORK_ACCESS_DENIED:
5973
	case STATUS_UNSUCCESSFUL:
5974
	  retstat = -EACCES;
5975
	  break;
5976
	case STATUS_GUARD_PAGE_VIOLATION:
5977
	case STATUS_INVALID_PARAMETER:
5978
	case STATUS_BAD_DEVICE_TYPE:
5979
	case STATUS_BAD_NETWORK_NAME:
5980
	case STATUS_INVALID_VOLUME_LABEL:
5981
	case STATUS_BAD_TOKEN_TYPE:
5982
	case STATUS_INVALID_GROUP_ATTRIBUTES:
5983
	case STATUS_BAD_MASTER_BOOT_RECORD:
5984
	case STATUS_INVALID_OPLOCK_PROTOCOL:
5985
	case STATUS_INVALID_INFO_CLASS:
5986
	case STATUS_INVALID_DEVICE_REQUEST:
5987
	case STATUS_INVALID_SYSTEM_SERVICE:
5988
	case STATUS_ILLEGAL_INSTRUCTION:
5989
	case STATUS_INVALID_LOCK_SEQUENCE:
5990
	case STATUS_INVALID_VIEW_SIZE:
5991
	case STATUS_INVALID_FILE_FOR_SECTION:
5992
	case STATUS_INVALID_DISPOSITION:
5993
	case STATUS_INVALID_UNWIND_TARGET:
5994
	case STATUS_INVALID_PORT_ATTRIBUTES:
5995
	case STATUS_INVALID_PARAMETER_MIX:
5996
	case STATUS_OBJECT_NAME_INVALID:
5997
	case STATUS_INVALID_VARIANT:
5998
	case STATUS_POWER_STATE_INVALID:
5999
	case STATUS_INVALID_DEVICE_OBJECT_PARAMETER:
6000
	case STATUS_INVALID_BLOCK_LENGTH:
6001
	  retstat = -EINVAL;
6002
	  break;
6003
#ifdef ENOMEDIUM
6004
	case STATUS_NO_MEDIA_IN_DEVICE:
6005
	case STATUS_UNRECOGNIZED_MEDIA:
6006
	  retstat = -ENOMEDIUM;
6007
	  break;
6008
#endif
6009
	case STATUS_SHARING_VIOLATION:
6010
	case STATUS_FILE_LOCK_CONFLICT:
6011
	case STATUS_LOCK_NOT_GRANTED:
6012
	case STATUS_SHARING_PAUSED:
6013
	case STATUS_SHARED_POLICY:
6014
	case STATUS_NOT_LOCKED:
6015
	case STATUS_PIPE_BUSY:
6016
	case STATUS_CONNECTION_IN_USE:
6017
	case STATUS_WAIT_FOR_OPLOCK:
6018
	  retstat = -EBUSY;
6019
	  break;
6020
	case STATUS_LOGON_FAILURE:
6021
	case STATUS_ACCOUNT_RESTRICTION:
6022
	case STATUS_ILL_FORMED_PASSWORD:
6023
	case STATUS_PASSWORD_RESTRICTION:
6024
	case STATUS_INVALID_LOGON_HOURS:
6025
	case STATUS_INVALID_WORKSTATION:
6026
	case STATUS_PASSWORD_EXPIRED:
6027
	case STATUS_ACCOUNT_DISABLED:
6028
	case STATUS_WRONG_PASSWORD:
6029
	case STATUS_SECTION_PROTECTION:
6030
	case STATUS_PRIVILEGE_NOT_HELD:
6031
	case STATUS_PRIVILEGED_INSTRUCTION:
6032
	case STATUS_PASSWORD_MUST_CHANGE:
6033
	case STATUS_ACCOUNT_LOCKED_OUT:
6034
	case STATUS_RESOURCE_NOT_OWNED:
6035
	case STATUS_LICENSE_VIOLATION:
6036
	case STATUS_LICENSE_QUOTA_EXCEEDED:
6037
	case STATUS_EVALUATION_EXPIRATION:
6038
	case STATUS_COPY_PROTECTION_FAILURE:
6039
	case STATUS_SMARTCARD_WRONG_PIN:
6040
	case STATUS_SMARTCARD_CARD_BLOCKED:
6041
	case STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED:
6042
	case STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT:
6043
	case STATUS_ACCESS_DISABLED_BY_POLICY_PATH:
6044
	case STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER:
6045
	case STATUS_ACCESS_DISABLED_BY_POLICY_OTHER:
6046
	case STATUS_CSS_AUTHENTICATION_FAILURE:
6047
	case STATUS_CSS_KEY_NOT_PRESENT:
6048
	case STATUS_CSS_KEY_NOT_ESTABLISHED:
6049
	case STATUS_INSUFFICIENT_LOGON_INFO:
6050
	  retstat = -EPERM;
6051
	  break;
6052
	case STATUS_DEVICE_DOES_NOT_EXIST:
6053
	case STATUS_DEVICE_NOT_CONNECTED:
6054
	case STATUS_DEVICE_POWER_FAILURE:
6055
	case STATUS_DEVICE_REMOVED:
6056
	case STATUS_PLUGPLAY_NO_DEVICE:
6057
	case STATUS_VOLUME_DISMOUNTED:
6058
	case STATUS_NOINTERFACE:
6059
	case STATUS_PARTITION_FAILURE:
6060
	  retstat = -ENODEV;
6061
	  break;
6062
	case STATUS_NO_MORE_FILES:
6063
	case STATUS_OBJECT_NAME_NOT_FOUND:
6064
	case STATUS_NOT_FOUND:
6065
	case STATUS_INVALID_PLUGPLAY_DEVICE_PATH:
6066
	case STATUS_NO_SUCH_FILE:
6067
	case STATUS_NETWORK_NAME_DELETED:
6068
	case STATUS_FILE_IS_OFFLINE:
6069
	case STATUS_MOUNT_POINT_NOT_RESOLVED:
6070
	  retstat = -ENOENT;
6071
	  break;
6072
	case STATUS_LOGON_SESSION_EXISTS:
6073
	case STATUS_DUPLICATE_NAME:
6074
	case STATUS_ALIAS_EXISTS:
6075
	case STATUS_ADDRESS_ALREADY_EXISTS:
6076
	case STATUS_DUPLICATE_OBJECTID:
6077
	case STATUS_OBJECTID_EXISTS:
6078
	  retstat = -EEXIST;
6079
	  break;
6080
	case STATUS_WRONG_VOLUME:
6081
	  retstat = -EXDEV;
6082
	  break;
6083
	case STATUS_BUFFER_TOO_SMALL:
6084
	case STATUS_SECTION_TOO_BIG:
6085
	case STATUS_SYSTEM_HIVE_TOO_LARGE:
6086
	  retstat = -E2BIG;
6087
	  break;
6088
	case STATUS_MEMORY_NOT_ALLOCATED:
6089
	case STATUS_NO_MEMORY:
6090
	case STATUS_INSUFFICIENT_RESOURCES:
6091
	case STATUS_INSUFF_SERVER_RESOURCES:
6092
	  retstat = -ENOMEM;
6093
	  break;
6094
	case STATUS_INVALID_HANDLE:
6095
	case STATUS_FILE_INVALID:
6096
	case STATUS_INVALID_PORT_HANDLE:
6097
	case STATUS_FILE_DELETED:
6098
	case STATUS_FILE_CLOSED:
6099
	case STATUS_FILE_CORRUPT_ERROR:
6100
	case STATUS_USER_MAPPED_FILE:
6101
	case STATUS_NOT_A_REPARSE_POINT:
6102
	case STATUS_DIRECTORY_IS_A_REPARSE_POINT:
6103
	case STATUS_FILE_NOT_ENCRYPTED:
6104
	case STATUS_FILE_ENCRYPTED:
6105
	case STATUS_CORRUPT_SYSTEM_FILE:
6106
	case STATUS_HANDLE_NOT_CLOSABLE:
6107
	  retstat = -EBADF;
6108
	  break;
6109
	case STATUS_FILES_OPEN:
6110
	  retstat = -EMFILE;
6111
	  break;
6112
	case STATUS_TOO_MANY_OPENED_FILES:
6113
	  retstat = -ENFILE;
6114
	  break;
6115
	case STATUS_PIPE_NOT_AVAILABLE:
6116
	case STATUS_INVALID_PIPE_STATE:
6117
	case STATUS_PIPE_BROKEN:
6118
	case STATUS_PIPE_EMPTY:
6119
	  retstat = -EPIPE;
6120
	  break;
6121
	case STATUS_DISK_FULL:
6122
	case STATUS_NO_LOG_SPACE:
6123
	case STATUS_LOG_FILE_FULL:
6124
	case STATUS_NO_SPOOL_SPACE:
6125
	case STATUS_PRINT_QUEUE_FULL:
6126
	case STATUS_DESTINATION_ELEMENT_FULL:
6127
	  retstat = -ENOSPC;
6128
	  break;
6129
	case STATUS_MEDIA_WRITE_PROTECTED:
6130
	  retstat = -EROFS;
6131
	  break;
6132
	case STATUS_DIRECTORY_NOT_EMPTY:
6133
	  retstat = -ENOTEMPTY;
6134
	  break;
6135
	case STATUS_RETRY:
6136
	  retstat = -EAGAIN;
6137
	  break;
6138
	case STATUS_OBJECT_PATH_NOT_FOUND:
6139
	case STATUS_NOT_A_DIRECTORY:
6140
	  retstat = -ENOTDIR;
6141
	  break;
6142
	case STATUS_FILE_IS_A_DIRECTORY:
6143
	  retstat = -EISDIR;
6144
	  break;
6145
	case STATUS_UNEXPECTED_IO_ERROR:
6146
	case STATUS_IO_PRIVILEGE_FAILED:
6147
	case STATUS_DEVICE_NOT_READY:
6148
	case STATUS_IO_DEVICE_ERROR:
6149
	case STATUS_OPEN_FAILED:
6150
	case STATUS_REPLY_MESSAGE_MISMATCH:
6151
	case STATUS_LOST_WRITEBEHIND_DATA:
6152
	  retstat = -EIO;
6153
	  break;
6154
	case STATUS_NOT_SUPPORTED:
6155
	case STATUS_ILLEGAL_FUNCTION:
6156
	case STATUS_WMI_NOT_SUPPORTED:
6157
	  retstat = -EOPNOTSUPP;
6158
	  break;
6159
	case STATUS_PIPE_DISCONNECTED:
6160
	case STATUS_CONNECTION_ABORTED:
6161
	case STATUS_CONNECTION_DISCONNECTED:
6162
	case STATUS_CONNECTION_RESET:
6163
	  retstat = -ECONNRESET;
6164
	  break;
6165
	default:
6166
	  break;
6167
  }
6168
6169
  return retstat;
6170
}
6171
6172
/** 
6173
 * rdpfs_parse_path - split path to path and stream name. 
6174
 * @org_path:       path to split 
6175
 * @path:       pointer to buffer in which parsed path saved 
6176
 * @stream_name:    pointer to buffer where stream name in unicode saved 
6177
 * 
6178
 * This function allocates buffers for @*path and @*stream, user must free them 
6179
 * after use. 
6180
 * 
6181
 * Return values: 
6182
 *  <0   Error occurred, return -errno; 
6183
 *   0  No stream name, @*stream is not allocated and set to AT_UNNAMED. 
6184
 *  >0   Stream name length in unicode characters. 
6185
 */
6186
static APP_CC
6187
ptrdiff_t rdpfs_parse_path(const char *org_path, char **path, char **stream_name) {
6188
  char * tmp_stream_name = (char *)NULL;
6189
  ptrdiff_t res = 0;
6190
6191
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6192
6193
  tmp_stream_name = (char *)g_strdup(org_path);
6194
  if (!tmp_stream_name) {
6195
    res = -1;
6196
  }
6197
  else {
6198
    *path = (char *)g_strsep(&tmp_stream_name, ":");
6199
    if (tmp_stream_name != NULL) {
6200
      *stream_name = (char *)g_strdup(tmp_stream_name);
6201
      res = g_strlen(*stream_name);
6202
    }
6203
  }
6204
6205
  return res;
6206
}
6207
6208
/****/
6209
6210
static int APP_CC input_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK * self, struct stream * s) {
6211
  int rv = 0;
6212
  int ml = 0;
6213
  int sl = 0;
6214
  int tl = 0;
6215
  char * tpos = (char *)NULL;
6216
6217
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6218
6219
  if (s != NULL && s->p != NULL && s->end != NULL && (s->end - s->p) > 4) {
6220
    tpos = s->p;
6221
  }
6222
  else {
6223
    tpos = NULL;
6224
  }
6225
  if (tpos == NULL || tpos[0] != 'X' || tpos[1] != 'S' || tpos[2] != 'y' || tpos[3] != 'm' || tpos[4] != '\n') {
6226
    rv = -1;
6227
  }
6228
  else {
6229
    in_uint8a(s, self->XSym, 4);
6230
    in_uint8s(s, 1);
6231
    tpos = s->p;
6232
    while (*tpos != '\n' && tpos < s->end && tl < 6) {
6233
      tl++;
6234
      tpos++;
6235
    }
6236
    if (tl == 0) {
6237
      rv = -1;
6238
      goto end;
6239
    }
6240
    in_uint8a(s, self->len, tl);
6241
    in_uint8s(s, 1);
6242
    tpos = s->p;
6243
    while (*tpos != '\n' && tpos < s->end && ml < 33) {
6244
      ml++;
6245
      tpos++;
6246
    }
6247
    if (ml == 0) {
6248
      rv = -1;
6249
      goto end;
6250
    }
6251
    in_uint8a(s, self->md5sum, ml);
6252
    in_uint8s(s, 1);
6253
    tpos = s->p;
6254
    while (*tpos != '\n' && tpos < s->end && sl < 1024) {
6255
      sl++;
6256
      tpos++;
6257
    }
6258
    if (sl == 0) {
6259
      rv = -1;
6260
      goto end;
6261
    }
6262
    in_uint8a(s, self->target, sl);
6263
    in_uint8s(s, 1);
6264
    rv = (4 + 1) + (tl + 1) + (ml + 1) + (sl + 1);
6265
  }
6266
  end:;
6267
  return rv;
6268
}
6269
6270
static int APP_CC send_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK * self, struct stream * s) {
6271
  int rv = 0;
6272
  int ml = 0;
6273
  int sl = 0;
6274
  int tl = 0;
6275
6276
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6277
6278
  if (self == NULL || s == NULL || self->len == NULL || self->md5sum == NULL || self->target == NULL || self->len[0] == '\0' || self->md5sum[0] == '\0' || self->target[0] == '\0' || self->XSym[0] != 'X' || self->XSym[1] != 'S' || self->XSym[2] != 'y' || self->XSym[3] != 'm') {
6279
    rv = -1;
6280
  }
6281
  else {
6282
    //tl = g_strlen(self->len);
6283
    tl = 5;
6284
    sl = g_atoi(self->len);
6285
    ml = 32;
6286
  }
6287
  if (ml < 1 || tl < 1 || sl < 1 || tl > 5 || sl > 1024 || ml > 32) {
6288
    rv = -1;
6289
  }
6290
  if (rv > -1) {
6291
    out_uint8a(s, self->XSym, 4);
6292
    out_uint8(s, '\n');
6293
    out_uint8a(s, self->len, tl);
6294
    out_uint8(s, '\n');
6295
    out_uint8a(s, self->md5sum, ml);
6296
    out_uint8(s, '\n');
6297
    out_uint8a(s, self->target, sl);
6298
    out_uint8(s, '\n');
6299
    rv = (4 + 1) + (tl + 1) + (ml + 1) + (sl + 1);
6300
  }
6301
  return rv;
6302
}
6303
6304
static char * APP_CC get_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK * self) {
6305
  char * rv = (char *)NULL;
6306
  ptrdiff_t sl = 0;
6307
6308
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6309
6310
  if (self != NULL && self->target != NULL && self->len != NULL) {
6311
    sl = g_atoi(self->len);
6312
    if (sl > 0) {
6313
      rv = (char *)g_malloc(sizeof(char) * (sl + 1), 1);
6314
      g_memcpy(rv,self->target,sl);
6315
    }
6316
  }
6317
  return rv;
6318
}
6319
6320
static int APP_CC set_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK * self, const char * val) {
6321
  int rv = 0;
6322
  ptrdiff_t sl = 0;
6323
  uint32_t state[4] = {0, 0, 0, 0};
6324
  MD5_CTX lmd5;
6325
  MD5_CTX * md5 = &lmd5;
6326
6327
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6328
6329
  if (self != NULL && val != NULL && g_strlen(val) > 0) {
6330
    sl = g_strlen(val);
6331
    if (sl > 0) {
6332
      g_memset(md5,0,sizeof(MD5_CTX));
6333
      MD5Init(md5);
6334
      MD5Update(md5, (unsigned char *)val, sl);
6335
      MD5Final((unsigned char *)state, md5);
6336
      g_snprintf(self->len,6,"%5.5d",sl);
6337
      g_snprintf(self->md5sum,33,"%08x%08x%08x%08x", htobel(state[0]), htobel(state[1]), htobel(state[2]), htobel(state[3]));
6338
      g_snprintf(self->target,MIN((sl + 1),1024),"%s",val);
6339
    }
6340
    else {
6341
      rv = -1;
6342
    }
6343
  }
6344
  else {
6345
    rv = -1;
6346
  }
6347
  return rv;
6348
}
6349
6350
static int APP_CC construct_MINSHALL_FRENCH_SYMLINK(MINSHALL_FRENCH_SYMLINK * self) {
6351
  int rv = 0;
6352
6353
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6354
6355
  if (self == NULL) {
6356
    rv = -1;
6357
  }
6358
  else {
6359
    g_memset(self,0,sizeof(MINSHALL_FRENCH_SYMLINK));
6360
    self->XSym[0] = 'X';
6361
    self->XSym[1] = 'S';
6362
    self->XSym[2] = 'y';
6363
    self->XSym[3] = 'm';
6364
    self->in = &input_MINSHALL_FRENCH_SYMLINK;
6365
    self->out = &send_MINSHALL_FRENCH_SYMLINK;
6366
    self->get = &get_MINSHALL_FRENCH_SYMLINK;
6367
    self->set = &set_MINSHALL_FRENCH_SYMLINK;
6368
  }
6369
  return rv;
6370
}
6371
6372
static int APP_CC send_INTERIX_DEV_FILE(INTERIX_DEV_FILE * self, struct stream * s) {
6373
  int rv = 0;
6374
6375
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6376
6377
  if (self == NULL || s == NULL || self->magic == NULL || self->magic[0] != 'I' || self->magic[1] != 'n' || self->magic[2] != 't' || self->magic[3] != 'x' || !((self->magic[4] == 'B' && self->magic[5] == 'L' && self->magic[6] == 'K') || (self->magic[4] == 'C' && self->magic[5] == 'H' && self->magic[6] == 'R')) || self->magic[7] != '\0') {
6378
    rv = -1;
6379
  }
6380
  else {
6381
    char * m = self->magic;
6382
    out_uint8a(s, m, 8);
6383
    out_uint64_le(s, self->major);
6384
    out_uint64_le(s, self->minor);
6385
  }
6386
6387
  return rv;
6388
}
6389
6390
6391
static int APP_CC set_INTERIX_DEV_FILE(INTERIX_DEV_FILE * self, const char dtype, int64_t dev_maj, int64_t dev_min) {
6392
  int rv = 0;
6393
  const char bdev[8] = {'I','n','t','x','B','L','K','\0'};
6394
  const char cdev[8] = {'I','n','t','x','C','H','R','\0'};
6395
  char * dmagic = (char *)NULL;
6396
  char tc = '\0';
6397
6398
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6399
6400
  if (self == NULL) {
6401
    rv = -1;
6402
    goto end_tag;
6403
  }
6404
  tc = (dtype == 'C' || dtype =='c') ? 'c' : (dtype == 'B' || dtype == 'b') ? 'b' : '\0';
6405
  if (tc == 'b') {
6406
    dmagic = (char *)bdev;
6407
  }
6408
  else if (tc == 'c') {
6409
    dmagic = (char *)cdev;
6410
  }
6411
  if (dmagic == NULL) {
6412
    rv = -1;
6413
    goto end_tag;
6414
  }
6415
  g_memcpy(self->magic,dmagic,8);
6416
  self->major = dev_maj;
6417
  self->minor = dev_min;
6418
6419
  end_tag:
6420
  return rv;
6421
}
6422
6423
static int APP_CC construct_INTERIX_DEV_FILE(INTERIX_DEV_FILE * self) {
6424
  int rv = 0;
6425
6426
  MDBGLOG("rdpfs", "INFO\t[%s()]: called", __func__);
6427
6428
  if (self == NULL) {
6429
    rv = -1;
6430
  }
6431
  else {
6432
    g_memset(self,0,sizeof(INTERIX_DEV_FILE));
6433
  }
6434
6435
  return rv;
6436
}
6437
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/rdpport.c (+2496 lines)
Line 0    Link Here 
1
/*
2
 *
3
 *  Serial port and/or parallel port redirection over RDP
4
 *
5
 */
6
7
#include "params.h"
8
9
#if defined(__linux__)
10
#include <asm/types.h>
11
#include <pty.h>
12
#endif
13
#include <ctype.h>
14
#include <errno.h>
15
#include <fcntl.h>
16
#include <stdbool.h>
17
#include <stdlib.h>
18
#include <stdio.h>
19
#include <string.h>
20
#include <termios.h>
21
#include <unistd.h>
22
#include <stdint.h>
23
#include <sys/types.h>
24
#include <sys/stat.h>
25
#include <sys/sysmacros.h>
26
#include <sys/un.h>
27
#include <sys/socket.h>
28
#include <sys/poll.h>
29
30
#include <arpa/inet.h>
31
32
33
#include "log.h"
34
#include "arch.h"
35
#include "parse.h"
36
#include "defines.h"
37
#include "rdpdr.h"
38
#include "rdpdr_methods.h"
39
#include "rdpport_defs.h"
40
#include "trans.h"
41
#include "devredir_defs.h"
42
#include "global.h"
43
#include "ntddser.h"
44
#include "crc32.h"
45
#include "thread_calls.h"
46
#include "thread_macros.h"
47
#include "dbg.h"
48
49
#define CN_TEST_IDX             CN_IDX_RDPUART
50
#define CN_TEST_VAL             CN_VAL_RDPUART
51
52
static int g_read_outstanding = 0;
53
static int g_keep_going = 1;
54
static int g_stop = 0;
55
static int g_fd = -1;
56
static int g_fhandle = -1;
57
static rdpport_t * g_port = (rdpport_t *)NULL;
58
59
static uint32_t seq = 0;
60
61
#ifndef MAX_REQID
62
#define MAX_REQID	25
63
#endif
64
65
static int g_irq_idx = -1;
66
static callback * g_irq_cb = (callback *)NULL;
67
static callback g_reqids[MAX_REQID];
68
static void * rdp_addport(void *);
69
static void * rdp_irq_callback(void *);
70
71
#ifndef MAX_MUTEX
72
#define MAX_MUTEX	25
73
#endif
74
75
typedef struct thread_head {
76
//	pthread_t *		thread;
77
	tc_t *			thread;
78
	struct thread_head *	next;
79
	struct thread_head *	prev;
80
} thread_head_t;
81
82
static thread_head_t * g_thread_list = (thread_head_t *)NULL;
83
84
extern tc_t g_mutex;
85
extern tc_p mut;
86
87
//static tc_t mutex_device_port;
88
static tc_t g_mutex_pcon_port;
89
static tc_t g_mutex_port;
90
static tc_t g_mutex_device_port;
91
static tc_t g_mutex_parent;
92
static tc_t g_mutex_portop;
93
static tc_t g_mutex_reqid;
94
static tc_t g_mutex_socket;
95
static tc_t g_mutex_thread_list;
96
static tc_p mutex_device_port = (tc_p)NULL;
97
static tc_p mutex_pcon_port = (tc_p)NULL;
98
static tc_p mutex_port = (tc_p)NULL;
99
static tc_p mutex_parent = (tc_p)NULL;
100
static tc_p mutex_portop = (tc_p)NULL;
101
static tc_p mutex_reqid = (tc_p)NULL;
102
static tc_p mutex_socket = (tc_p)NULL;
103
static tc_p mutex_thread_list = (tc_p)NULL;
104
105
static int APP_CC rdpport_cycle(rdpport_t *);
106
static int APP_CC issue_port_cmd(rdpport_t *, const rdpdr_packet_t *restrict);
107
108
static int APP_CC get_reqid_port(int *);
109
static int APP_CC free_reqid_port(int);
110
static int APP_CC init_reqids_port(void);
111
static int APP_CC retrieve_reqid_port(int);
112
static int APP_CC get_mutex_port(int, tc_p *);
113
static int APP_CC get_cv_port(int, tc_p *);
114
static int APP_CC ntstatus_to_errcode(DWORD);
115
116
extern char * APP_CC ntstatus_string(uint32_t);
117
118
static int APP_CC parent_data_in_port(struct trans *);
119
120
121
/*****************************************************************************/
122
/*****		child process-related section				******/
123
/*****************************************************************************/
124
125
126
/*****************************************************************************/
127
static int APP_CC
128
parent_data_in_port(struct trans * trans) {
129
  struct stream * s = (struct stream *)NULL;
130
  int rdpport_opcode = 0;
131
  int rdpport_reply = 0;
132
  int size = 0;
133
  int error = 0;
134
  int fault = 0;
135
  int fhandle = 0;
136
  int uniqid = 0;
137
  int fdone = 0;
138
  uint32_t magic = 0;
139
  uint32_t device_id = 0;
140
  uint32_t crc32 = 0;
141
  uint32_t calc_crc32 = 0;
142
  rdpport_t * port = (rdpport_t *)NULL;
143
  BYTE buf[MAX_STREAM];
144
145
  MDBGLOG("port","parent_data_in_port(): called");
146
147
  g_memset((BYTE *)buf,0,sizeof(BYTE)*MAX_STREAM);
148
149
  if (trans == 0) {
150
    return 0;
151
  }
152
  //TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
153
  //TC_MUTEX_LOCK((tc_p)mutex_parent);
154
  s = (struct stream *)trans_get_in_s(trans);
155
  in_uint32_le(s, magic);
156
  in_uint32_le(s, rdpport_reply);
157
  in_uint32_le(s, size);
158
  in_uint32_le(s, device_id);
159
  in_uint32_le(s, fhandle);
160
  in_uint32_le(s, uniqid);
161
  in_uint32_le(s, crc32);
162
  if (size > 0) {
163
    error = trans_force_read(trans, size);
164
    calc_crc32 = Crc32_ComputeBuf(0, (void *)((char *)(s->p) + 28), size);
165
    MDBGLOG("redir", "INFO\t[%s()]: crc32 = 0x%8.8x, calc_crc32 = 0x%8.8x", __func__, crc32, calc_crc32);
166
  }
167
  if (error == 0) {
168
    /* the entire message block has been read in, so process it: */
169
    fault = ((rdpport_reply | RDPPORT_ERROR) == rdpport_reply) ? 1 : 0;
170
    rdpport_opcode = rdpport_reply & (~(RDPPORT_REPLY | RDPPORT_ERROR));
171
    MDBGLOG("port"," ** parent_data_in_port(): rdpport_opcode = 0x%8.8x; rdpport_reply = 0x%8.8x; fault = %d; device_id = %d; uniqid = %d",rdpport_opcode,rdpport_reply,fault,device_id,uniqid);
172
    if (fault > 0) {
173
      NTSTATUS iostatus = { .Value = 0x00000000 };
174
      int reqid = -1;
175
      callback * cbdata = (callback *)NULL;
176
      tc_p lmut = (tc_p)NULL;
177
      tc_p lcv = (tc_p)NULL;
178
      char * nterr = (char *)NULL;
179
180
      TC_MUTEX_LOCK((tc_p)mutex_portop);
181
      in_uint32_le(s, iostatus.Value);
182
183
      nterr = ntstatus_string(iostatus.Value);
184
      MDBGLOG("port"," --> FAULT: \"%s\" (status = 0x%8.8x)",nterr,iostatus.Value);
185
      cbdata = &(g_reqids[uniqid]);
186
      reqid = cbdata->opid;
187
      if (reqid > -1) {
188
	get_mutex_port(reqid, &lmut);
189
	if (lmut != 0) {
190
	  TC_MUTEX_LOCK((tc_p)lmut);
191
	  TC_MUTEX_UNLOCK((tc_p)mutex_portop);
192
	  cbdata->IoStatus.Value = iostatus.Value;
193
	  get_cv_port(reqid, &lcv);
194
	  if (lcv != 0) {
195
	    TC_COND_SIGNAL((tc_p)lcv);
196
	  }
197
	}
198
      }
199
      else {
200
	lmut = mutex_portop;
201
      }
202
      if (lmut != 0) {
203
	TC_MUTEX_UNLOCK((tc_p)lmut);
204
      }
205
    }
206
    else switch(rdpport_opcode) {
207
      case RDPPORT_OPEN:
208
	MDBGLOG("port"," ^^ (RDPPORT_OPEN)");
209
	{
210
	  DR_DRIVE_CREATE_RSP iorsp;
211
	  int reqid = -1;
212
	  int tsize = 0;
213
	  callback * cbdata = NULL;
214
	  tc_p lmut = (tc_p)NULL;
215
	  tc_p lcv = (tc_p)NULL;
216
	  LOCAL_STREAM(v);
217
	  TC_MUTEX_LOCK((tc_p)mutex_portop);
218
	  reqid = retrieve_reqid_port(uniqid);
219
	  cbdata = &(g_reqids[reqid]);
220
	  get_mutex_port(reqid, &lmut);
221
	  TC_MUTEX_LOCK((tc_p)lmut);
222
	  TC_MUTEX_UNLOCK((tc_p)mutex_portop);
223
	  get_cv_port(reqid, &lcv);
224
	  construct_DR_DRIVE_CREATE_RSP(&iorsp);
225
	  if (size > 0 && size < MAX_STREAM) {
226
	    get_DR_DRIVE_CREATE_RSP(&iorsp, s);
227
	  }
228
	  cbdata->FileId = iorsp.DeviceCreateResponse.FileId;
229
	  MDBGLOG("port"," --> FileId = %d; fhandle = %d",cbdata->FileId,fhandle);
230
	  send_DR_DRIVE_CREATE_RSP(&iorsp, v);
231
	  s_mark_end(v);
232
	  tsize = v->end - v->data;
233
	  //g_hexdump_file("/tmp/taskq_port_open_reply.hexdump",v->data,tsize);
234
	  TC_COND_SIGNAL((tc_p)lcv);
235
	  TC_MUTEX_UNLOCK((tc_p)lmut);
236
	}
237
	break;
238
      case RDPPORT_READ:
239
	MDBGLOG("port"," ^^ (RDPPORT_READ)");
240
	{
241
	  DR_DRIVE_READ_RSP iorsp;
242
	  int reqid = -1;
243
	  int tsize = 0;
244
	  callback * cbdata = (callback *)NULL;
245
	  tc_p lmut = (tc_p)NULL;
246
	  tc_p lcv = (tc_p)NULL;
247
	  LOCAL_STREAM(v);
248
	  TC_MUTEX_LOCK((tc_p)mutex_portop);
249
	  reqid = retrieve_reqid_port(uniqid);
250
	  cbdata = &(g_reqids[reqid]);
251
	  get_mutex_port(reqid, &lmut);
252
	  TC_MUTEX_LOCK((tc_p)lmut);
253
	  TC_MUTEX_UNLOCK((tc_p)mutex_portop);
254
	  construct_DR_READ_RSP(&iorsp);
255
	  if (size > 0 && size < MAX_STREAM) {
256
	    iorsp.ReadData = cbdata->userdata;
257
	    get_DR_READ_RSP(&iorsp, s);
258
	  }
259
	  cbdata->length = iorsp.Length;
260
	  send_DR_READ_RSP(&iorsp, v);
261
	  s_mark_end(v);
262
	  tsize = v->end - v->data;
263
	  get_cv_port(reqid,&lcv);
264
	  TC_COND_SIGNAL((tc_p)lcv);
265
	  TC_MUTEX_UNLOCK((tc_p)lmut);
266
	  MDBGLOG("port"," ^^ (RDPPORT_READ): iorsp.Length = %d; iorsp.ReadData = \"%s\"",iorsp.Length,iorsp.ReadData);
267
	}
268
	break;
269
      case RDPPORT_WRITE:
270
	MDBGLOG("port"," ^^ (RDPPORT_WRITE)");
271
	{
272
	  DR_DRIVE_WRITE_RSP iorsp;
273
	  int reqid = -1;
274
	  //callback * cbdata = (callback *)NULL;
275
	  callback * cbdata = (callback *)NULL;
276
	  tc_p lmut = (tc_p)NULL;
277
	  tc_p lcv = (tc_p)NULL;
278
	  TC_MUTEX_LOCK((tc_p)mutex_portop);
279
	  reqid = retrieve_reqid_port(uniqid);
280
	  if (reqid < 0) {
281
	    cbdata = &(g_reqids[uniqid]);
282
	    reqid = cbdata->opid;
283
	  }
284
	  else {
285
	    cbdata = &(g_reqids[reqid]);
286
	  }
287
	  //cbdata = &(g_reqids[uniqid]);
288
//	  reqid = retrieve_reqid_port(uniqid);
289
//	  cbdata = &(g_reqids[reqid]);
290
	  //reqid = cbdata->opid;
291
	  get_mutex_port(reqid, &lmut);
292
	  TC_MUTEX_LOCK((tc_p)lmut);
293
	  TC_MUTEX_UNLOCK((tc_p)mutex_portop);
294
	  construct_DR_WRITE_RSP(&iorsp);
295
	  get_DR_WRITE_RSP(&iorsp, s);
296
	  cbdata->length = iorsp.Length;
297
	  get_cv_port(reqid,&lcv);
298
	  TC_COND_SIGNAL((tc_p)lcv);
299
	  TC_MUTEX_UNLOCK((tc_p)lmut);
300
	}
301
	break;
302
      case RDPPORT_IOCTL:
303
	MDBGLOG("port"," ^^ (RDPPORT_IOCTL)");
304
	{
305
	  DR_CONTROL_RSP iorsp;
306
	  int reqid = -1;
307
	  callback * cbdata = (callback *)NULL;
308
	  tc_p lmut = (tc_p)NULL;
309
	  tc_p lcv = (tc_p)NULL;
310
	  TC_MUTEX_LOCK((tc_p)mutex_portop);
311
	  reqid = retrieve_reqid_port(uniqid);
312
	  if (reqid < 0) {
313
	    cbdata = &(g_reqids[uniqid]);
314
	    reqid = cbdata->opid;
315
	  }
316
	  else {
317
	    cbdata = &(g_reqids[reqid]);
318
	  }
319
	  get_mutex_port(reqid, &lmut);
320
	  TC_MUTEX_LOCK((tc_p)lmut);
321
	  TC_MUTEX_UNLOCK((tc_p)mutex_portop);
322
	  construct_DR_CONTROL_RSP(&iorsp);
323
	  iorsp.OutputBufferLength = cbdata->length;
324
	  if (cbdata->userdata != NULL) {
325
	    iorsp.OutputBuffer = cbdata->userdata;
326
	  }
327
	  else if (cbdata->length > 0) {
328
	    iorsp.OutputBuffer = (void *)g_malloc(cbdata->length, 1);
329
	  }
330
	  MDBGLOG("port"," -- about to call get_DR_CONTROL_RDP()...");
331
	  get_DR_CONTROL_RSP(&iorsp, s);
332
	  MDBGLOG("port"," -- get_DR_CONTROL_RDP() done.");
333
	  cbdata->length = iorsp.OutputBufferLength;
334
	  if (cbdata->length > 0) {
335
	    cbdata->userdata = (BYTE *)g_malloc(cbdata->length, 1);
336
	    g_memcpy(cbdata->userdata, iorsp.OutputBuffer, cbdata->length);
337
	  }
338
	  if ((cbdata->flags & CBFLAG_FUNC) || (cbdata->flags & CBFLAG_SUPPRESS) || ((cbdata->flags & CBFLAG_CMD) && (cbdata->cmd == IOCTL_SERIAL_WAIT_ON_MASK))) {
339
	    MDBGLOG("port"," ^^ (RDPPORT_IOCTL): about to execute callback function...");
340
	    if (cbdata->call != NULL && g_stop < 1) {
341
	      callback * tcb = (callback *)NULL;
342
	      tc_t * lthread = (tc_t *)NULL;
343
	      thread_head_t * thead = (thread_head_t *)NULL;
344
	      thead = (thread_head_t *)g_malloc(sizeof(thread_head_t), 1);
345
	      lthread = (tc_t *)g_malloc(sizeof(tc_t), 1);
346
	      thead->thread = lthread;
347
	      tcb = (callback *)g_malloc(sizeof(callback), 1);
348
	      g_memcpy(tcb, cbdata, sizeof(callback));
349
	      TC_MUTEX_LOCK((tc_p)mutex_thread_list);
350
	      if (g_thread_list == NULL) {
351
		thead->next = thead;
352
		thead->prev = thead;
353
	      }
354
	      else {
355
		thead->next = g_thread_list;
356
		thead->prev = g_thread_list->prev;
357
		g_thread_list->prev = thead;
358
	      }
359
	      g_thread_list = thead;
360
	      TC_THREAD_INIT(&(thead->thread->thread), cbdata->call, tcb);
361
	      TC_MUTEX_UNLOCK((tc_p)mutex_thread_list);
362
	      TC_MUTEX_UNLOCK((tc_p)lmut);
363
	      lmut = NULL;
364
	    }
365
	    else {
366
	      //MDBGLOG("port"," ^^ (RDPPORT_IOCTL): callback ERROR");
367
	    }
368
	    MDBGLOG("port"," ^^ (RDPPORT_IOCTL): callback done.");
369
	  }
370
	  else if (!(cbdata->flags & CBFLAG_SUPPRESS)) {
371
	    MDBGLOG("port"," ^^ (RDPPORT_IOCTL): about to signal lcv...");
372
	    get_cv_port(reqid,&lcv);
373
	    if (lcv != 0) {
374
	      TC_COND_SIGNAL((tc_p)lcv);
375
	    }
376
	    else {
377
	      MDBGLOG("port"," ^^ (RDPPORT_IOCTL): ERROR (lcv == 0)");
378
	    }
379
	    MDBGLOG("port"," ^^ (RDPPORT_IOCTL): lcv signaled.");
380
	  }
381
//	  if (lmut > -1) {
382
	  if (lmut > (tc_p)NULL) {
383
	    TC_MUTEX_UNLOCK((tc_p)lmut);
384
	  }
385
	  MDBGLOG("port"," ^^ (RDPPORT_IOCTL): iorsp.OutputBufferLength = %d",iorsp.OutputBufferLength);
386
	}
387
	break;
388
      case RDPPORT_CLOSE:
389
	MDBGLOG("port"," ^^ (RDPPORT_CLOSE)");
390
	{
391
	  int reqid = -1;
392
	  callback * cbdata = (callback *)NULL;
393
	  tc_p lmut = (tc_p)NULL;
394
	  tc_p lcv = (tc_p)NULL;
395
	  TC_MUTEX_LOCK((tc_p)mutex_portop);
396
	  reqid = retrieve_reqid_port(uniqid);
397
	  if (reqid < 0) {
398
	    cbdata = &(g_reqids[uniqid]);
399
	    reqid = cbdata->opid;
400
	  }
401
	  else {
402
	    cbdata = &(g_reqids[reqid]);
403
	  }
404
//	  reqid = retrieve_reqid_port(uniqid);
405
//	  cbdata = &(g_reqids[reqid]);
406
	  //reqid = cbdata->opid;
407
	  get_mutex_port(reqid, &lmut);
408
	  TC_MUTEX_LOCK((tc_p)lmut);
409
	  TC_MUTEX_UNLOCK((tc_p)mutex_portop);
410
	  get_cv_port(reqid,&lcv);
411
	  TC_COND_SIGNAL((tc_p)lcv);
412
	  TC_MUTEX_UNLOCK((tc_p)lmut);
413
	}
414
	break;
415
      case RDPPORT_INIT:
416
	MDBGLOG("port"," ^^ (RDPPORT_INIT)");
417
	{
418
	  int reqid = -1;
419
	  callback * cbdata = (callback *)NULL;
420
	  filelist * lst = (filelist *)NULL;
421
	  tc_p lmut = (tc_p)NULL;
422
	  tc_p lcv = (tc_p)NULL;
423
	}
424
	break;
425
      case RDPPORT_DESTROY:
426
	MDBGLOG("port"," ^^ (RDPPORT_DESTROY)");
427
	break;
428
      case RDPPORT_ERROR:
429
	MDBGLOG("port"," ^^ (RDPPORT_ERROR)");
430
	break;
431
    }
432
  }
433
  //TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
434
  //TC_MUTEX_UNLOCK((tc_p)mutex_parent);
435
  return error;
436
}
437
438
439
/*****************************************************************************/
440
static int socket_send(const int s, const struct rdpdr_packet * msg) {
441
	unsigned int size = 0;
442
	int err = 0;
443
	int done = 0;
444
	int cum = 0;
445
	int rem = 0;
446
	char buf[4096];
447
	void * pkt = (void *)buf;
448
449
	g_memset(buf, 0, sizeof(char) * 4096);
450
451
	TC_MUTEX_LOCK((tc_p)mutex_socket);
452
	size = sizeof(struct rdpdr_packet_header) + (sizeof(uint8_t) * msg->size);
453
454
	g_memcpy(buf, msg, size);
455
	err = g_tcp_send(s, pkt, size, 0);
456
	TC_MUTEX_UNLOCK((tc_p)mutex_socket);
457
458
	return err;
459
}
460
461
462
/*****************************************************************************/
463
/*****************************************************************************/
464
465
466
typedef struct _handle_port_loop_args {
467
	rdpport_t *		port;
468
	struct trans *		pcon;
469
	tbus			objs[2];
470
	int			num_objs;
471
	int			timeout;
472
	int			check_parent;
473
	int			check_device;
474
} handle_port_loop_args;
475
476
static void * APP_CC
477
loop_parent_port(void * inargs) {
478
  handle_port_loop_args * largs = (handle_port_loop_args *)inargs;
479
  rdpport_t * port = largs->port;
480
  struct trans * pcon = largs->pcon;
481
  tbus * objs = (tbus *)(largs->objs);
482
  int num_objs = largs->num_objs;
483
  int timeout = largs->timeout;
484
  int check_parent = largs->check_parent;
485
  int check_device = largs->check_device;
486
  tbus obj = -1;
487
  if (num_objs > 0 && check_parent > 0) {
488
    obj = objs[0];
489
  }
490
  objs = (tbus *)&obj;
491
  num_objs = 1;
492
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_parent > 0) {
493
    /* handle any inbound communication from the parent process: */
494
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
495
      if ((check_parent > 0) && g_is_wait_obj_set(objs[0])) {
496
	//TC_MUTEX_LOCK((tc_p)mutex_parent);
497
	if (trans_check_wait_objs(pcon) != 0) {
498
	  MDBGLOG("port","ERROR [loop_parent_port()]: ");
499
	  break;
500
	}
501
	//TC_MUTEX_UNLOCK((tc_p)mutex_parent);
502
	g_reset_wait_obj(objs[0]);
503
      }
504
    }
505
  }
506
  MDBGLOG("port","INFO\t[%s()]: exiting thread",__func__);
507
  tc_thread_exit(NULL);
508
}
509
510
static void * APP_CC
511
loop_device_port(void * inargs) {
512
  handle_port_loop_args * largs = (handle_port_loop_args *)inargs;
513
  rdpport_t * port = largs->port;
514
  struct trans * pcon = largs->pcon;
515
  tbus * objs = (tbus *)(largs->objs);
516
  int tcnt = 0;
517
  int num_objs = largs->num_objs;
518
  int timeout = largs->timeout;
519
  int check_parent = largs->check_parent;
520
  int check_device = largs->check_device;
521
  tbus obj = -1;
522
  if (num_objs > 1 && check_device > 0) {
523
    obj = objs[1];
524
  }
525
  else if (num_objs == 1 && check_device > 0) {
526
    obj = objs[0];
527
  }
528
  objs = (tbus *)&obj;
529
  num_objs = 1;
530
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_device > 0) {
531
    rdp_irq_data_t * data = (rdp_irq_data_t *)NULL;
532
    rdpdr_packet_t * reply = (rdpdr_packet_t *)NULL;
533
    char buf[MAX_STREAM];
534
    reply = (rdpdr_packet_t *)buf;
535
    data = (rdp_irq_data_t *)(&(reply->data));
536
    data->type = RDP_M_OPEN;
537
    issue_port_cmd(port, reply);
538
    data->type = RDP_M_START;
539
    issue_port_cmd(port, reply);
540
    /* handle communication from pseudo-device (i.e., the artificial serial or parallel port on the server): */
541
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
542
      if (g_is_wait_obj_set(obj)) {
543
	rdpport_cycle(port);
544
      }
545
    }
546
  }
547
  g_keep_going = 0;
548
  tc_thread_exit(NULL);
549
}
550
551
/*****************************************************************************/
552
static int APP_CC
553
rdpport_cycle(rdpport_t * port) {
554
  ptrdiff_t rv = 0;
555
  ptrdiff_t res = 0;
556
  tbus fd = 0;
557
  size_t bufsize = 0;
558
  unsigned char proceed = 0;
559
  char buf[MAX_STREAM];
560
561
  g_memset((char *)buf,0,sizeof(buf));
562
  g_port = port;
563
  g_fd = port->child_sck;
564
  fd = port->fd;
565
  MDBGLOG("port","INFO\t[%s()]: called (fd = %d)",__func__,fd);
566
  if (buf == NULL) {
567
    MDBGLOG("port","ERROR\t[%s()]: failed to allocate read buffer",__func__);
568
    rv = -1;
569
  }
570
  else {
571
    while (!proceed) {
572
      ptrdiff_t len = 0;
573
      rdp_irq_data_t * data = (rdp_irq_data_t *)NULL;
574
      rdpdr_packet_t * reply = (rdpdr_packet_t *)NULL;
575
      char buf[MAX_STREAM];
576
577
      g_memset(buf, 0, sizeof(char) * 4096);
578
      reply = (rdpdr_packet_t *)buf;
579
      data = (rdp_irq_data_t *)(&(reply->data));
580
581
      res = g_file_read(fd,data->rx_buf,(MAX_STREAM - sizeof(rdp_irq_data_t)));
582
      if (res == -EINTR) {
583
	MDBGLOG("port","INFO\t[%s()]: continue...",__func__);
584
	continue;
585
      }
586
      else if (res >= 0) {
587
	MDBGLOG("port","INFO\t[%s()]: proceed = 1",__func__);
588
	proceed = 1;
589
	data->rx_len += res;
590
      }
591
      else if (res < 0) {
592
	MDBGLOG("port","ERROR\t[%s()]: res = %d",__func__,res);
593
	break;
594
      }
595
596
      if (proceed) {
597
	if (data->rx_len > 0) {
598
	  data->type = RDP_M_WRITE;
599
	}
600
	issue_port_cmd(port, reply);
601
	g_memset(buf,0,sizeof(buf));
602
      }
603
    }
604
  }
605
  return rv;
606
}
607
608
static int APP_CC issue_port_cmd(rdpport_t * port, const rdpdr_packet_t *restrict ipkt) {
609
	int rv = 0;
610
	tbus fd = -1;
611
	uint32_t crc32 = 0;
612
	ptrdiff_t olen = 0;
613
	ptrdiff_t len = 0;
614
	unsigned char send_reply = 1;
615
	void * odata = (void *)NULL;
616
	struct stat st;
617
	struct trans * pcon = (struct trans *)NULL;
618
	tc_p lmutex = (tc_p)NULL;
619
	tc_p lcv = (tc_p)NULL;
620
	callback * cbdata = NULL;
621
	void * subdata = (void *)NULL;
622
	struct stream * s = (struct stream *)NULL;
623
	int retstat = 0;
624
	int rdpport_opcode = 0x00000000;
625
	ptrdiff_t size = 0x00000000;
626
	int reqid = -1;
627
	int uniqid = 0;
628
	tbus fhandle = 0;
629
	ptrdiff_t seqid = 0;
630
	ptrdiff_t idx = 0;
631
	int val = 0;
632
	int ack = 0;
633
	int cmd = 0;
634
	size_t sublen = 0;
635
	const uint32_t magic = RDP_PACKET_MAGIC;
636
	uint32_t device_id = 0;
637
	uint32_t * p_crc32 = (uint32_t *)NULL;
638
	char * p = (char *)NULL;
639
	rdpdr_packet_t *restrict reply = (rdpdr_packet_t *restrict)ipkt;
640
	rdp_irq_data_t * data = (rdp_irq_data_t *)(&(reply->data));
641
642
	fd = port->fd;
643
	uniqid = reply->uniqid;
644
	cmd = data->type;
645
	sublen = data->rx_len;
646
	subdata = (void *)(data->rx_buf);
647
	fhandle = reply->fhandle;
648
649
	switch (cmd) {
650
	  case RDP_M_SETMCTRL:
651
	      {
652
		uint32_t cmd		= 0x00000000;
653
		const uint32_t ibuflen	= 0x00000000;
654
		const uint32_t obuflen	= 0x00000000;
655
		const BYTE * ibuf = (const BYTE *)NULL;
656
		const BYTE * obuf = (const BYTE *)NULL;
657
		int set_rts = 0;
658
		int set_dtr = 0;
659
		uint32_t mreg = 0;
660
661
		// ***
662
		// ***	BEGIN:	PART I
663
		// ***
664
665
		TC_MUTEX_LOCK((tc_p)mutex_portop);
666
		get_reqid_port(&reqid);
667
		get_mutex_port(reqid, &lmutex);
668
		TC_MUTEX_LOCK((tc_p)lmutex);
669
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
670
671
		rdpport_opcode = RDPPORT_IOCTL;
672
		size = 0;
673
		uniqid = reqid;
674
675
		get_cv_port(reqid, &lcv);
676
677
		mreg |= (ibuflen == sizeof(uint8_t)) ? *((uint8_t *)(subdata)) : (ibuflen == sizeof(uint32_t)) ? *((uint32_t *)(subdata)) : 0x00000000;
678
		MDBGLOG("port","INFO\t[%s()]: (IOCTL_SERIAL_SET_MODEM_CONTROL) mreg = 0x%8.8x",__func__,mreg);
679
		set_dtr = (mreg & SERIAL_IOC_MCR_DTR) ? 1 : 0;
680
		set_rts = (mreg & SERIAL_IOC_MCR_RTS) ? 1 : 0;
681
682
		cmd = (set_dtr) ? IOCTL_SERIAL_SET_DTR : IOCTL_SERIAL_CLR_DTR;
683
684
		get_cv_port(reqid, &lcv);
685
		cbdata = &(g_reqids[reqid]);
686
		cbdata->port = port;
687
		cbdata->length = obuflen;
688
		cbdata->userdata = (BYTE *)NULL;
689
		cbdata->opcode = rdpport_opcode;
690
		cbdata->cmd = cmd;
691
		cbdata->flags = CBFLAG_PORT | CBFLAG_MUTEX | CBFLAG_INTERMEDIATE | CBFLAG_CMD;
692
693
		rdpport_opcode = RDPPORT_IOCTL;
694
		size = 0;
695
		uniqid = reqid;
696
697
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
698
		pcon = port->ccon;
699
		pcon->callback_data = cbdata;
700
		s = trans_get_out_s(pcon, MAX_STREAM);
701
		out_uint32_le(s, magic);
702
		out_uint32_le(s, rdpport_opcode);
703
		out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen) + ibuflen));
704
		out_uint32_le(s, device_id);
705
		out_uint32_le(s, fhandle);
706
		out_uint32_le(s, uniqid);
707
		p_crc32 = (uint32_t *)s_get_pos(s);
708
		out_uint32_le(s, crc32);
709
		p = s_get_pos(s);
710
		out_uint32_le(s, cmd);
711
		out_uint32_le(s, ibuflen);
712
		out_uint32_le(s, obuflen);
713
		s_mark_end(s);
714
		size = s->end - s->data;
715
		if (s->end > p) {
716
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
717
		}
718
719
		trans_force_write(pcon);
720
		g_memset(s->data,0,MAX_STREAM);
721
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
722
723
		MDBGLOG("port","entering g_obj_wait loop:");
724
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
725
		MDBGLOG("port","exiting g_obj_wait loop.");
726
727
		// ***
728
		// ***	END:	PART I
729
		// ***
730
731
		// ***
732
		// ***	BEGIN:	PART II	(RTS)
733
		// ***
734
735
		cmd = (set_rts) ? IOCTL_SERIAL_SET_RTS : IOCTL_SERIAL_CLR_RTS;
736
737
		get_cv_port(reqid, &lcv);
738
		cbdata = &(g_reqids[reqid]);
739
		cbdata->port = port;
740
		cbdata->length = obuflen;
741
		cbdata->userdata = (BYTE *)NULL;
742
		cbdata->opcode = rdpport_opcode;
743
		cbdata->cmd = cmd;
744
		cbdata->flags = CBFLAG_PORT | CBFLAG_MUTEX | CBFLAG_INTERMEDIATE | CBFLAG_CMD;
745
746
		rdpport_opcode = RDPPORT_IOCTL;
747
		size = 0;
748
		uniqid = reqid;
749
750
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
751
		pcon = port->ccon;
752
		pcon->callback_data = cbdata;
753
		s = trans_get_out_s(pcon, MAX_STREAM);
754
		out_uint32_le(s, magic);
755
		out_uint32_le(s, rdpport_opcode);
756
		out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen) + ibuflen));
757
		out_uint32_le(s, device_id);
758
		out_uint32_le(s, fhandle);
759
		out_uint32_le(s, uniqid);
760
		p_crc32 = (uint32_t *)s_get_pos(s);
761
		out_uint32_le(s, crc32);
762
		p = s_get_pos(s);
763
		out_uint32_le(s, cmd);
764
		out_uint32_le(s, ibuflen);
765
		out_uint32_le(s, obuflen);
766
		s_mark_end(s);
767
		size = s->end - s->data;
768
		if ((s->end - p) > 0) {
769
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
770
		}
771
772
		trans_force_write(pcon);
773
		g_memset(s->data,0,MAX_STREAM);
774
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
775
776
		MDBGLOG("port","entering g_obj_wait loop:");
777
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
778
		MDBGLOG("port","exiting g_obj_wait loop.");
779
780
		TC_MUTEX_UNLOCK((tc_p)lmutex);
781
		cbdata->userdata = NULL;
782
		free_reqid_port(reqid);
783
784
	      }
785
	      MDBGLOG("port","INFO\t[%s()]: RDPUART_SETMCTRL done.", __func__);
786
	      break;
787
788
	  case RDP_M_GETMCTRL:
789
	      {
790
791
		uint32_t cmd		= 0x00000000;
792
		uint32_t ibuflen	= 0x00000000;
793
		uint32_t obuflen	= 0x00000000;
794
		BYTE * ibuf = (BYTE *)NULL;
795
		BYTE * obuf = (BYTE *)NULL;
796
		unsigned long * mreg = (unsigned long *)NULL;
797
798
		TC_MUTEX_LOCK((tc_p)mutex_portop);
799
		get_reqid_port(&reqid);
800
		get_mutex_port(reqid, &lmutex);
801
		TC_MUTEX_LOCK((tc_p)lmutex);
802
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
803
804
		get_cv_port(reqid, &lcv);
805
		cbdata = &(g_reqids[reqid]);
806
		cbdata->port = port;
807
808
		rdpport_opcode = RDPPORT_IOCTL;
809
		cmd = IOCTL_SERIAL_GET_MODEM_CONTROL;
810
		obuflen = sizeof(unsigned long);
811
		size = 0;
812
		uniqid = reqid;
813
814
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
815
		pcon = port->ccon;
816
		pcon->callback_data = cbdata;
817
		s = trans_get_out_s(pcon, MAX_STREAM);
818
		out_uint32_le(s, magic);
819
		out_uint32_le(s, rdpport_opcode);
820
		out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen)) + ibuflen);
821
		out_uint32_le(s, device_id);
822
		out_uint32_le(s, fhandle);
823
		out_uint32_le(s, uniqid);
824
		p_crc32 = (uint32_t *)s_get_pos(s);
825
		out_uint32_le(s, crc32);
826
		p = s_get_pos(s);
827
		out_uint32_le(s, cmd);
828
		out_uint32_le(s, ibuflen);
829
		out_uint32_le(s, obuflen);
830
		if (ibuflen > 0 && ibuf != NULL) {
831
		  out_uint8a(s, ibuf, ibuflen);
832
		}
833
		s_mark_end(s);
834
		size = s->end - s->data;
835
		if ((s->end - p) > 0) {
836
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
837
		}
838
839
		//g_hexdump_file("/tmp/taskq_port_getmctrl.hexdump", s->data, size);
840
		MDBGLOG("port"," ** rdpport_getmctrl(): sending [g_fd = %d, fhandle = %d]", g_fd, fhandle);
841
		trans_force_write(pcon);
842
		g_memset(s->data,0,MAX_STREAM);
843
		MDBGLOG("port","sent.");
844
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
845
846
		MDBGLOG("port","entering g_obj_wait loop:");
847
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
848
		MDBGLOG("port","exiting g_obj_wait loop.");
849
850
		mreg = (unsigned long *)cbdata->userdata;
851
		odata = cbdata->userdata;
852
		olen = sizeof(unsigned long *);
853
854
		MDBGLOG("port"," .. MCR = 0x%8.8x", *mreg);
855
856
		cbdata->userdata = NULL;
857
		TC_MUTEX_UNLOCK((tc_p)lmutex);
858
		free_reqid_port(reqid);
859
860
	      }
861
	      break;
862
863
	  case RDP_M_GETSTATUS:
864
	      {
865
	      }
866
	      break;
867
868
	  case RDP_M_OPEN:
869
	      {
870
		uint32_t	flags		= 0x00000000;
871
		uint32_t	share		= 0x00000000;
872
		uint32_t	options		= 0x00000000;
873
		uint32_t	attributes	= 0x00000000;
874
		uint32_t	access		= 0x00000000;
875
876
		TC_MUTEX_LOCK((tc_p)mutex_portop);
877
		get_reqid_port(&reqid);
878
		get_mutex_port(reqid, &lmutex);
879
		TC_MUTEX_LOCK((tc_p)lmutex);
880
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
881
882
		get_cv_port(reqid, &lcv);
883
		cbdata = &(g_reqids[reqid]);
884
		cbdata->port = port;
885
886
		rdpport_opcode = RDPPORT_OPEN;
887
		size = 0;
888
		uniqid = reqid;
889
890
		flags		|= (FILE_WRITE_DATA | FILE_READ_DATA);
891
		share		|= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
892
		access		|= SYNCHRONIZE | FILE_READ_ATTRIBUTES;
893
		options		|= FILE_OPEN;
894
895
		cbdata->opcode = rdpport_opcode;
896
		cbdata->uniqid = uniqid;
897
		cbdata->CompletionId = uniqid;
898
		cbdata->opid = reqid;
899
		cbdata->fd = fd;
900
		cbdata->type = 0;
901
		cbdata->flags = CBFLAG_FINAL | CBFLAG_PORT;
902
903
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
904
		pcon = port->ccon;
905
		pcon->callback_data = cbdata;
906
		s = trans_get_out_s(pcon, MAX_STREAM);
907
		out_uint32_le(s, magic);
908
		out_uint32_le(s, rdpport_opcode);
909
		out_uint32_le(s, size + (sizeof(flags) + sizeof(share) + sizeof(options) + sizeof(attributes)));
910
		out_uint32_le(s, device_id);
911
		out_uint32_le(s, fhandle);
912
		out_uint32_le(s, uniqid);
913
		p_crc32 = (uint32_t *)s_get_pos(s);
914
		out_uint32_le(s, crc32);
915
		p = s_get_pos(s);
916
		out_uint32_le(s, flags);
917
		out_uint32_le(s, share);
918
		out_uint32_le(s, options);
919
		out_uint32_le(s, attributes);
920
		s_mark_end(s);
921
		size = s->end - s->data;
922
		if ((s->end - p) > 0) {
923
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
924
		}
925
926
		g_hexdump_file("/tmp/taskq_port_open.hexdump", s->data, size);
927
		MDBGLOG("port"," ** rdpport_open(): sending [g_fd = %d]", g_fd);
928
		trans_force_write(pcon);
929
		g_memset(s->data,0,MAX_STREAM);
930
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
931
		MDBGLOG("port","sent.");
932
933
		MDBGLOG("port","entering g_obj_wait loop:");
934
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
935
		MDBGLOG("port","exiting g_obj_wait loop.");
936
		fhandle = cbdata->FileId;
937
938
		g_fhandle = fhandle;
939
		port->fhandle = fhandle;
940
941
		if (cbdata->userdata != NULL) {
942
		  g_free(cbdata->userdata);
943
		}
944
		cbdata->userdata = NULL;
945
946
		olen = sizeof(uint32_t);
947
		odata = (void *)g_malloc(olen, 1);
948
		*((uint32_t *)odata) |= fhandle;
949
950
		TC_MUTEX_UNLOCK((tc_p)lmutex);
951
		free_reqid_port(reqid);
952
953
	      }
954
	      break;
955
956
	  case RDP_M_CLOSE:
957
	      {
958
		TC_MUTEX_LOCK((tc_p)mutex_portop);
959
		get_reqid_port(&reqid);
960
		get_mutex_port(reqid, &lmutex);
961
		TC_MUTEX_LOCK((tc_p)lmutex);
962
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
963
964
		fhandle = g_fhandle;
965
966
		get_cv_port(reqid, &lcv);
967
		cbdata = &(g_reqids[reqid]);
968
		cbdata->port = port;
969
970
		rdpport_opcode = RDPPORT_CLOSE;
971
		size = 0;
972
		uniqid = reqid;
973
974
		cbdata->opcode = rdpport_opcode;
975
		cbdata->uniqid = uniqid;
976
		cbdata->CompletionId = uniqid;
977
		cbdata->opid = reqid;
978
		cbdata->fd = fd;
979
		cbdata->type = 0;
980
		cbdata->flags = CBFLAG_FINAL | CBFLAG_PORT;
981
982
//		out_uint32_le(s, magic);
983
//		p_crc32 = (uint32_t *)s_get_pos(s);
984
//		out_uint32_le(s, crc32);
985
//		p = s_get_pos(s);
986
//		if ((s->end - p) > 0) {
987
//		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
988
//		}
989
990
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
991
		pcon = port->ccon;
992
		pcon->callback_data = cbdata;
993
		s = trans_get_out_s(pcon, MAX_STREAM);
994
		out_uint32_le(s, magic);
995
		out_uint32_le(s, rdpport_opcode);
996
		out_uint32_le(s, size);
997
		out_uint32_le(s, device_id);
998
		out_uint32_le(s, fhandle);
999
		out_uint32_le(s, uniqid);
1000
		out_uint32_le(s, crc32);
1001
		s_mark_end(s);
1002
		size = s->end - s->data;
1003
1004
		//g_hexdump_file("/tmp/taskq_port_close.hexdump", s->data, size);
1005
		MDBGLOG("port"," ** rdpport_close(): sending [g_fd = %d]", g_fd);
1006
		trans_force_write(pcon);
1007
		g_memset(s->data,0,MAX_STREAM);
1008
		MDBGLOG("port","sent.");
1009
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1010
1011
		MDBGLOG("port","entering g_obj_wait loop:");
1012
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
1013
		MDBGLOG("port","exiting g_obj_wait loop.");
1014
1015
		g_fhandle = -1;
1016
		port->fhandle = -1;
1017
1018
		TC_MUTEX_UNLOCK((tc_p)lmutex);
1019
		free_reqid_port(reqid);
1020
	      }
1021
	      break;
1022
1023
	  case RDP_M_READ:
1024
	      {
1025
1026
		uint32_t obuflen	= 0x00000001;
1027
		const uint64_t offset	= 0x0000000000000000;
1028
		int lreqid		= -1;
1029
		tc_p llmutex		= (tc_p)NULL;
1030
1031
		get_reqid_port(&lreqid);
1032
		get_mutex_port(lreqid, &llmutex);
1033
		TC_MUTEX_LOCK((tc_p)llmutex);
1034
1035
		get_cv_port(lreqid, &lcv);
1036
		cbdata = &(g_reqids[lreqid]);
1037
		cbdata->port = port;
1038
		cbdata->userdata = (void *)g_malloc(1, 1);
1039
1040
		rdpport_opcode = RDPPORT_READ;
1041
		size = 0;
1042
		uniqid = lreqid;
1043
1044
		cbdata->opcode = rdpport_opcode;
1045
		cbdata->uniqid = uniqid;
1046
		cbdata->CompletionId = uniqid;
1047
		cbdata->opid = lreqid;
1048
		cbdata->fd = fd;
1049
		cbdata->type = 0;
1050
		cbdata->flags = CBFLAG_FINAL | CBFLAG_PORT;
1051
1052
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1053
		pcon = port->ccon;
1054
		pcon->callback_data = cbdata;
1055
		s = trans_get_out_s(pcon, MAX_STREAM);
1056
		out_uint32_le(s, magic);
1057
		out_uint32_le(s, rdpport_opcode);
1058
		out_uint32_le(s, (size + sizeof(uint32_t) + sizeof(uint64_t)));
1059
		out_uint32_le(s, device_id);
1060
		out_uint32_le(s, fhandle);
1061
		out_uint32_le(s, uniqid);
1062
		p_crc32 = (uint32_t *)s_get_pos(s);
1063
		out_uint32_le(s, crc32);
1064
		p = s_get_pos(s);
1065
		out_uint32_le(s, obuflen);
1066
		out_uint64_le(s, offset);
1067
		s_mark_end(s);
1068
		size = s->end - s->data;
1069
		if ((s->end - p) > 0) {
1070
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1071
		}
1072
1073
		//g_hexdump_file("/tmp/taskq_port_read.hexdump", s->data, size);
1074
		MDBGLOG("port"," ** rdpport_read(): sending [g_fd = %d, fhandle = %d, obuflen = %d]", g_fd, fhandle, obuflen);
1075
		trans_force_write(pcon);
1076
		g_memset(s->data,0,MAX_STREAM);
1077
		MDBGLOG("port","sent.");
1078
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1079
1080
		MDBGLOG("port","entering g_obj_wait loop:");
1081
		tc_cond_wait((tc_p)lcv, (tc_p)llmutex);
1082
		MDBGLOG("port","exiting g_obj_wait loop.");
1083
1084
		odata = cbdata->userdata;
1085
		olen = obuflen;
1086
1087
		MDBGLOG("port"," .. *odata = %c", *((unsigned char *)odata));
1088
1089
		cbdata->userdata = NULL;
1090
		TC_MUTEX_UNLOCK((tc_p)llmutex);
1091
		free_reqid_port(lreqid);
1092
1093
		g_read_outstanding = 0;
1094
1095
	      }
1096
	      break;
1097
1098
	  case RDP_M_WRITE:
1099
	      {
1100
		const uint32_t ibuflen	= (const uint32_t)sublen;
1101
		const uint64_t offset	= 0x0000000000000000;
1102
		BYTE * ibuf = (BYTE *)subdata;
1103
1104
		TC_MUTEX_LOCK((tc_p)mutex_portop);
1105
		get_reqid_port(&reqid);
1106
		get_mutex_port(reqid, &lmutex);
1107
		TC_MUTEX_LOCK((tc_p)lmutex);
1108
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
1109
1110
		get_cv_port(reqid, &lcv);
1111
		cbdata = &(g_reqids[reqid]);
1112
		cbdata->port = port;
1113
1114
		rdpport_opcode = RDPPORT_WRITE;
1115
		size = 0;
1116
		uniqid = reqid;
1117
1118
		cbdata->opcode = rdpport_opcode;
1119
		cbdata->uniqid = uniqid;
1120
		cbdata->CompletionId = uniqid;
1121
		cbdata->opid = reqid;
1122
		cbdata->fd = fd;
1123
		cbdata->type = 0;
1124
		cbdata->flags = CBFLAG_FINAL | CBFLAG_PORT;
1125
1126
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1127
		pcon = port->ccon;
1128
		pcon->callback_data = cbdata;
1129
		s = trans_get_out_s(pcon, MAX_STREAM);
1130
		out_uint32_le(s, magic);
1131
		out_uint32_le(s, rdpport_opcode);
1132
		out_uint32_le(s, (size + sizeof(uint32_t) + sizeof(uint64_t) + ibuflen));
1133
		out_uint32_le(s, device_id);
1134
		out_uint32_le(s, fhandle);
1135
		out_uint32_le(s, uniqid);
1136
		p_crc32 = (uint32_t *)s_get_pos(s);
1137
		out_uint32_le(s, crc32);
1138
		p = s_get_pos(s);
1139
		out_uint32_le(s, ibuflen);
1140
		out_uint64_le(s, offset);
1141
		if (ibuflen > 0 && ibuf != NULL) {
1142
		  out_uint8a(s, ibuf, ibuflen);
1143
		}
1144
		s_mark_end(s);
1145
		size = s->end - s->data;
1146
		if ((s->end - p) > 0) {
1147
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1148
		}
1149
1150
		MDBGLOG("port"," ** rdpport_write(): sending [g_fd = %d, fhandle = %d, ibuflen = %d]", g_fd, fhandle, ibuflen);
1151
		trans_force_write(pcon);
1152
		g_memset(s->data,0,MAX_STREAM);
1153
		MDBGLOG("port","sent.");
1154
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1155
1156
		MDBGLOG("port","entering g_obj_wait loop:");
1157
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
1158
		MDBGLOG("port","exiting g_obj_wait loop.");
1159
1160
		MDBGLOG("port"," .. *ibuf = %c", *((unsigned char *)ibuf));
1161
1162
		cbdata->userdata = NULL;
1163
		TC_MUTEX_UNLOCK((tc_p)lmutex);
1164
		free_reqid_port(reqid);
1165
1166
	      }
1167
	      break;
1168
1169
	  case RDP_M_DATA:
1170
	      {
1171
	      }
1172
	      break;
1173
1174
	  case RDP_M_START:
1175
	      {
1176
1177
		/*
1178
		 *
1179
		 *	Upon startup, this code simulates UART interrupts by
1180
		 *	causing a "DR_CONTROL_REQ"-type IRP to be issued to the
1181
		 *	RDP client, with a command of IOCTL_SERIAL_SET_WAIT_MASK
1182
		 *	followed by a IOCTL_SERIAL_WAIT_ON_MASK command (which only
1183
		 *	returns when the specified wait mask criteria are met).
1184
		 *	Other IRPs may be processed normally (and simultaneously)
1185
		 *	while the DR_CONTROL_REQ remains pending.  This "dormant"
1186
		 *	behavior permits the illusion of interrupt-based operation.
1187
		 *
1188
		 */
1189
1190
		uint32_t cmd		= 0x00000000;
1191
		uint32_t ibuflen	= 0x00000000;
1192
		uint32_t obuflen	= 0x00000000;
1193
		uint32_t * mask		= (uint32_t *)NULL;
1194
		BYTE * ibuf = (BYTE *)NULL;
1195
		BYTE * obuf = (BYTE *)NULL;
1196
1197
		mask = (uint32_t *)g_malloc(sizeof(uint32_t), 1);
1198
1199
		// ***
1200
		// ***	BEGIN:	PART I
1201
		// ***
1202
1203
		TC_MUTEX_LOCK((tc_p)mutex_portop);
1204
		get_reqid_port(&reqid);
1205
		get_mutex_port(reqid, &lmutex);
1206
		TC_MUTEX_LOCK((tc_p)lmutex);
1207
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
1208
1209
		rdpport_opcode = RDPPORT_IOCTL;
1210
		cmd = IOCTL_SERIAL_SET_WAIT_MASK;
1211
		*mask = SERIAL_EV_RXCHAR	| SERIAL_EV_BREAK 
1212
			| SERIAL_EV_CTS		| SERIAL_EV_DSR 
1213
			| SERIAL_EV_ERR		| SERIAL_EV_RING 
1214
			| SERIAL_EV_RLSD	| SERIAL_EV_RXFLAG
1215
			| SERIAL_EV_TXEMPTY;
1216
		ibuflen = sizeof(*mask);
1217
		ibuf = (void *)mask;
1218
		size = 0;
1219
		uniqid = reqid;
1220
1221
		get_cv_port(reqid, &lcv);
1222
		cbdata = &(g_reqids[reqid]);
1223
		cbdata->port = port;
1224
		cbdata->length = 0;
1225
		cbdata->userdata = (BYTE *)NULL;
1226
		cbdata->opcode = rdpport_opcode;
1227
		cbdata->cmd = cmd;
1228
		cbdata->mask = *mask;
1229
		cbdata->flags = CBFLAG_PORT | CBFLAG_IRQ | CBFLAG_MUTEX | CBFLAG_INTERMEDIATE | CBFLAG_CMD | CBFLAG_MASK;
1230
1231
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1232
		pcon = port->ccon;
1233
		pcon->callback_data = cbdata;
1234
		s = trans_get_out_s(pcon, MAX_STREAM);
1235
		out_uint32_le(s, magic);
1236
		out_uint32_le(s, rdpport_opcode);
1237
		out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen) + ibuflen));
1238
		out_uint32_le(s, device_id);
1239
		out_uint32_le(s, fhandle);
1240
		out_uint32_le(s, uniqid);
1241
		p_crc32 = (uint32_t *)s_get_pos(s);
1242
		out_uint32_le(s, crc32);
1243
		p = s_get_pos(s);
1244
		out_uint32_le(s, cmd);
1245
		out_uint32_le(s, ibuflen);
1246
		out_uint32_le(s, obuflen);
1247
		if (ibuflen > 0 && ibuf != NULL) {
1248
		  out_uint32_le(s, *ibuf);
1249
		}
1250
		s_mark_end(s);
1251
		size = s->end - s->data;
1252
		if ((s->end - p) > 0) {
1253
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1254
		}
1255
1256
		MDBGLOG("port"," ** rdpport_setwaitmask(): sending [g_fd = %d, fhandle = %d, *mask = %d]", g_fd, fhandle, *mask);
1257
		trans_force_write(pcon);
1258
		g_memset(s->data,0,MAX_STREAM);
1259
		MDBGLOG("port","sent.");
1260
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1261
1262
		MDBGLOG("port","entering g_obj_wait loop:");
1263
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
1264
		MDBGLOG("port","exiting g_obj_wait loop.");
1265
1266
		TC_MUTEX_LOCK((tc_p)mutex_portop);
1267
		TC_MUTEX_UNLOCK((tc_p)lmutex);
1268
		free_reqid_port(reqid);
1269
1270
		MDBGLOG("port","\t- - - now, proceeding to IOCTL_SERIAL_WAIT_ON_MASK...");
1271
1272
		// ***
1273
		// ***	END:	PART I
1274
		// ***
1275
1276
		// ***
1277
		// ***	BEGIN:	PART II
1278
		// ***
1279
1280
		get_reqid_port(&reqid);
1281
		get_mutex_port(reqid, &lmutex);
1282
		TC_MUTEX_LOCK((tc_p)lmutex);
1283
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
1284
1285
		cbdata = &(g_reqids[reqid]);
1286
1287
		rdpport_opcode = RDPPORT_IOCTL;
1288
		cmd = IOCTL_SERIAL_WAIT_ON_MASK;
1289
		ibuflen = 0;
1290
		ibuf = NULL;
1291
		obuflen = sizeof(ULONG);
1292
		size = 0;
1293
		uniqid = reqid;
1294
1295
		cbdata->call = &rdp_irq_callback;
1296
		cbdata->cmd = cmd;
1297
		cbdata->flags = CBFLAG_PORT | CBFLAG_IRQ | CBFLAG_MUTEX | CBFLAG_FUNC | CBFLAG_CMD | CBFLAG_MASK;
1298
		cbdata->opid = reqid;
1299
		cbdata->CompletionId = uniqid;
1300
		cbdata->uniqid = uniqid;
1301
		cbdata->port = port;
1302
		cbdata->FileId = fhandle;
1303
		cbdata->opcode = rdpport_opcode;
1304
		cbdata->mask = *mask;
1305
1306
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1307
		g_irq_cb = cbdata;
1308
		g_irq_idx = reqid;
1309
		pcon = port->ccon;
1310
		pcon->callback_data = cbdata;
1311
		s = trans_get_out_s(pcon, MAX_STREAM);
1312
		out_uint32_le(s, magic);
1313
		out_uint32_le(s, rdpport_opcode);
1314
		out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen) + ibuflen));
1315
		out_uint32_le(s, device_id);
1316
		out_uint32_le(s, fhandle);
1317
		out_uint32_le(s, uniqid);
1318
		p_crc32 = (uint32_t *)s_get_pos(s);
1319
		out_uint32_le(s, crc32);
1320
		p = s_get_pos(s);
1321
		out_uint32_le(s, cmd);
1322
		out_uint32_le(s, ibuflen);
1323
		out_uint32_le(s, obuflen);
1324
		s_mark_end(s);
1325
		size = s->end - s->data;
1326
		if ((s->end - p) > 0) {
1327
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1328
		}
1329
1330
		//g_hexdump_file("/tmp/taskq_port_waitonmask.hexdump", s->data, size);
1331
		MDBGLOG("port"," ** rdpport_waitonmask(): sending [g_fd = %d, fhandle = %d, reqid = %d, cbdata->CompletionId = %d, cbdata->uniqid = %d, cbdata->opid = %d, cbdata->cmd = 0x%8.8x]", g_fd, fhandle, reqid, cbdata->CompletionId, cbdata->uniqid, cbdata->opid, cbdata->cmd);
1332
		trans_force_write(pcon);
1333
		TC_MUTEX_UNLOCK((tc_p)lmutex);
1334
		g_memset(s->data,0,MAX_STREAM);
1335
		MDBGLOG("port","sent.");
1336
		//MDBGLOG("port"," - - - WAITING ON MASK...");
1337
		g_stop = 0;
1338
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1339
		//MDBGLOG("port"," - - - ...");
1340
1341
		// ***
1342
		// ***	END:	PART II
1343
		// ***
1344
	      }
1345
	      MDBGLOG("port", "RDPUART_START: done.");
1346
	      break;
1347
1348
	  case RDP_M_STOP:
1349
	      {
1350
		g_stop = 1;
1351
1352
		uint32_t cmd		= 0x00000000;
1353
		uint32_t ibuflen	= 0x00000000;
1354
		uint32_t obuflen	= 0x00000000;
1355
		uint32_t * mask		= (uint32_t *)NULL;
1356
		BYTE * ibuf = (BYTE *)NULL;
1357
		BYTE * obuf = (BYTE *)NULL;
1358
1359
		mask = (uint32_t *)g_malloc(sizeof(uint32_t), 1);
1360
1361
		TC_MUTEX_LOCK((tc_p)mutex_portop);
1362
		get_reqid_port(&reqid);
1363
		get_mutex_port(reqid, &lmutex);
1364
		TC_MUTEX_LOCK((tc_p)lmutex);
1365
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
1366
1367
		rdpport_opcode = RDPPORT_IOCTL;
1368
		cmd = IOCTL_SERIAL_SET_WAIT_MASK;
1369
		*mask = 0x00000000;
1370
		ibuflen = sizeof(*mask);
1371
		ibuf = (void *)mask;
1372
		size = 0;
1373
		uniqid = reqid;
1374
1375
		get_cv_port(reqid, &lcv);
1376
		cbdata = &(g_reqids[reqid]);
1377
		cbdata->port = port;
1378
		cbdata->length = 0;
1379
		cbdata->userdata = (BYTE *)NULL;
1380
		cbdata->opcode = rdpport_opcode;
1381
		cbdata->cmd = cmd;
1382
		cbdata->mask = *mask;
1383
		cbdata->flags = CBFLAG_PORT | CBFLAG_IRQ | CBFLAG_MUTEX | CBFLAG_FINAL | CBFLAG_CMD | CBFLAG_MASK;
1384
1385
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1386
		pcon = port->ccon;
1387
		pcon->callback_data = cbdata;
1388
		s = trans_get_out_s(pcon, MAX_STREAM);
1389
		out_uint32_le(s, magic);
1390
		out_uint32_le(s, rdpport_opcode);
1391
		out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen) + ibuflen));
1392
		out_uint32_le(s, device_id);
1393
		out_uint32_le(s, fhandle);
1394
		out_uint32_le(s, uniqid);
1395
		p_crc32 = (uint32_t *)s_get_pos(s);
1396
		out_uint32_le(s, crc32);
1397
		p = s_get_pos(s);
1398
		out_uint32_le(s, cmd);
1399
		out_uint32_le(s, ibuflen);
1400
		out_uint32_le(s, obuflen);
1401
		if (ibuflen > 0 && ibuf != NULL) {
1402
		  out_uint32_le(s, *ibuf);
1403
		}
1404
		s_mark_end(s);
1405
		size = s->end - s->data;
1406
		if ((s->end - p) > 0) {
1407
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1408
		}
1409
1410
		trans_force_write(pcon);
1411
		g_memset(s->data,0,MAX_STREAM);
1412
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1413
1414
		MDBGLOG("port","entering g_obj_wait loop:");
1415
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
1416
		MDBGLOG("port","exiting g_obj_wait loop.");
1417
1418
		TC_MUTEX_UNLOCK((tc_p)lmutex);
1419
		free_reqid_port(reqid);
1420
1421
	      }
1422
	      break;
1423
1424
	  case RDP_M_GETBAUD:
1425
	      {
1426
	      }
1427
	      break;
1428
1429
	  case RDP_M_SETBAUD:
1430
	      {
1431
	      }
1432
	      break;
1433
1434
	  case RDP_M_TXEMPTY:
1435
	      {
1436
		uint32_t cmd		= 0x00000000;
1437
		uint32_t ibuflen	= 0x00000000;
1438
		uint32_t obuflen	= 0x00000000;
1439
		BYTE * ibuf = (BYTE *)NULL;
1440
		BYTE * obuf = (BYTE *)NULL;
1441
		SERIAL_STATUS lserstat;
1442
		SERIAL_STATUS * serstat = (SERIAL_STATUS *)NULL;
1443
1444
		g_memset(&lserstat, 0, sizeof(SERIAL_STATUS));
1445
		serstat = &lserstat;
1446
1447
		TC_MUTEX_LOCK((tc_p)mutex_portop);
1448
		get_reqid_port(&reqid);
1449
		get_mutex_port(reqid, &lmutex);
1450
		TC_MUTEX_LOCK((tc_p)lmutex);
1451
		TC_MUTEX_UNLOCK((tc_p)mutex_portop);
1452
1453
		get_cv_port(reqid, &lcv);
1454
		cbdata = &(g_reqids[reqid]);
1455
		cbdata->port = port;
1456
		cbdata->userdata = (void *)(&lserstat);
1457
1458
		rdpport_opcode = RDPPORT_IOCTL;
1459
		cmd = IOCTL_SERIAL_GET_COMMSTATUS;
1460
		obuflen = sizeof(SERIAL_STATUS);
1461
		size = 0;
1462
		uniqid = reqid;
1463
1464
		cbdata->opcode = rdpport_opcode;
1465
		cbdata->uniqid = uniqid;
1466
		cbdata->CompletionId = uniqid;
1467
		cbdata->opid = reqid;
1468
		cbdata->fd = fd;
1469
		cbdata->type = 0;
1470
		cbdata->flags = CBFLAG_FINAL | CBFLAG_PORT;
1471
1472
		TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1473
		pcon = port->ccon;
1474
		pcon->callback_data = cbdata;
1475
		s = trans_get_out_s(pcon, MAX_STREAM);
1476
		out_uint32_le(s, magic);
1477
		out_uint32_le(s, rdpport_opcode);
1478
		out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen)) + ibuflen);
1479
		out_uint32_le(s, device_id);
1480
		out_uint32_le(s, fhandle);
1481
		out_uint32_le(s, uniqid);
1482
		p_crc32 = (uint32_t *)s_get_pos(s);
1483
		out_uint32_le(s, crc32);
1484
		p = s_get_pos(s);
1485
		out_uint32_le(s, cmd);
1486
		out_uint32_le(s, ibuflen);
1487
		out_uint32_le(s, obuflen);
1488
		if (ibuflen > 0 && ibuf != NULL) {
1489
		  out_uint8a(s, ibuf, ibuflen);
1490
		}
1491
		s_mark_end(s);
1492
		size = s->end - s->data;
1493
		if ((s->end - p) > 0) {
1494
		  *p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
1495
		}
1496
1497
		//g_hexdump_file("/tmp/taskq_port_txempty.hexdump", s->data, size);
1498
		MDBGLOG("port"," ** rdpport_txempty(): sending [g_fd = %d, fhandle = %d]", g_fd, fhandle);
1499
		trans_force_write(pcon);
1500
		g_memset(s->data,0,MAX_STREAM);
1501
		MDBGLOG("port","sent.");
1502
		TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1503
1504
		MDBGLOG("port","entering g_obj_wait loop:");
1505
		tc_cond_wait((tc_p)lcv, (tc_p)lmutex);
1506
		MDBGLOG("port","exiting g_obj_wait loop.");
1507
1508
		olen = sizeof(unsigned char);
1509
		odata = (void *)g_malloc(olen, 1);
1510
		*((unsigned char *)odata) = (serstat->AmountInOutQueue == 0) ? 1 : 0;
1511
1512
		MDBGLOG("port"," .. serstat->AmountInOutQueue = %d", serstat->AmountInOutQueue);
1513
1514
		cbdata->userdata = NULL;
1515
		TC_MUTEX_UNLOCK((tc_p)lmutex);
1516
		free_reqid_port(reqid);
1517
	      }
1518
	      break;
1519
1520
	  case RDP_M_TXFULL:
1521
	      {
1522
	      }
1523
	      break;
1524
1525
	  case RDP_M_TXSTOP:
1526
	      {
1527
	      }
1528
	      break;
1529
1530
	  case RDP_M_TXSTART:
1531
	      {
1532
	      }
1533
	      break;
1534
1535
	  case RDP_M_RXEMPTY:
1536
	      {
1537
	      }
1538
	      break;
1539
1540
	  case RDP_M_RXFULL:
1541
	      {
1542
	      }
1543
	      break;
1544
1545
	  case RDP_M_RXSTOP:
1546
	      {
1547
	      }
1548
	      break;
1549
1550
	  case RDP_M_RXSTART:
1551
	      {
1552
	      }
1553
	      break;
1554
1555
	  case RDP_M_MSENABLE:
1556
	      {
1557
	      }
1558
	      break;
1559
1560
	  case RDP_M_BREAKCTL:
1561
	      {
1562
	      }
1563
	      break;
1564
1565
	  case RDP_M_SETTERMIOS:
1566
	      {
1567
	      }
1568
	      break;
1569
1570
	  case RDP_M_IOCTL:
1571
	      {
1572
	      }
1573
	      break;
1574
1575
	  case RDP_M_ASYNC:
1576
	      {
1577
	      }
1578
	      break;
1579
1580
	  case RDP_M_REPLY:
1581
	      {
1582
	      }
1583
	      break;
1584
1585
	  default:
1586
	      {
1587
	      }
1588
	      break;
1589
	}
1590
	if (send_reply > 0) {
1591
	  unsigned char * tp = (unsigned char *)NULL;
1592
	  unsigned char tbuf[4096];
1593
	  rdpdr_packet_t * pkt = (rdpdr_packet_t *)tbuf;
1594
	  memset(pkt, 0, sizeof(rdpdr_packet_t));
1595
	  pkt->size = olen;
1596
	  if (olen > 0 && odata != NULL) {
1597
	    g_memcpy(&(pkt->data), odata, olen);
1598
	  }
1599
	  len = socket_send(fd, pkt);
1600
	}
1601
1602
	return rv;
1603
}
1604
1605
/*****************************************************************************/
1606
rdpport_t * APP_CC
1607
rdpport_main(int type, int seq) {
1608
  rdpport_t * rv = (rdpport_t *)NULL;
1609
1610
  rv = (rdpport_t *)g_malloc(sizeof(rdpport_t), 1);
1611
  rv->type = type;
1612
  rv->fd = -1;
1613
1614
  MDBGLOG("port","rdpport_main(): done.");
1615
1616
  return rv;
1617
}
1618
1619
/*****************************************************************************/
1620
int APP_CC
1621
handle_port(tbus sck, rdpport_t * port) {
1622
  int rv = 0;
1623
  int brk = 0;
1624
  tbus s = 0;
1625
  tbus fd = 0;
1626
  tbus objs[2] = { -1, -1 };
1627
  int num_objs = 0;
1628
  int timeout = 0;
1629
  int check_parent = 0;
1630
  int check_device = 0;
1631
  struct trans * pcon = (struct trans *)NULL;
1632
  callback cb;
1633
  handle_port_loop_args largs;
1634
  tc_t thread_parent;
1635
  tc_t thread_device;
1636
  tc_t thread_poll;
1637
  int node_num = 0;
1638
  const char node_base[] = "/tmp/.sock_rdp_%d";
1639
  char node_buf[256];
1640
1641
  // MDBGLOG("port","handle_port(): sck = %d", sck);
1642
1643
  g_memset(node_buf,0,sizeof(node_buf));
1644
  g_memset(&cb,0,sizeof(callback));
1645
  g_memset(&largs,0,sizeof(handle_port_loop_args));
1646
  g_memset(&thread_parent,0,sizeof(tc_t));
1647
  g_memset(&thread_device,0,sizeof(tc_t));
1648
  g_memset(&thread_poll,0,sizeof(tc_t));
1649
1650
  g_keep_going = 1;
1651
1652
  //mut = (tbus)&g_mutex;
1653
  mutex_pcon_port = (tc_p)&g_mutex_pcon_port;
1654
  mutex_port = (tc_p)&g_mutex_port;
1655
  mutex_portop = (tc_p)&g_mutex_portop;
1656
  mutex_parent = (tc_p)&g_mutex_parent;
1657
  mutex_device_port = (tc_p)&g_mutex_device_port;
1658
  mutex_reqid = (tc_p)&g_mutex_reqid;
1659
  mutex_socket = (tc_p)&g_mutex_socket;
1660
  mutex_thread_list = (tc_p)&g_mutex_thread_list;
1661
  //TC_MUTEX_INIT((tc_p)mut,NULL);
1662
  TC_MUTEX_INIT((tc_p)mutex_pcon_port,NULL);
1663
  TC_MUTEX_INIT((tc_p)mutex_port,NULL);
1664
  TC_MUTEX_INIT((tc_p)mutex_portop,NULL);
1665
  TC_MUTEX_INIT((tc_p)mutex_parent,NULL);
1666
  TC_MUTEX_INIT((tc_p)mutex_device_port,NULL);
1667
  TC_MUTEX_INIT((tc_p)mutex_reqid,NULL);
1668
  TC_MUTEX_INIT((tc_p)mutex_socket,NULL);
1669
  TC_MUTEX_INIT((tc_p)mutex_thread_list,NULL);
1670
1671
  TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1672
  TC_MUTEX_LOCK((tc_p)mutex_port);
1673
  
1674
1675
  MDBGLOG("port","handle_port(): (mutex_pcon_port and mutex_port locked) [1]");
1676
  init_reqids_port();
1677
  MDBGLOG("port","handle_port(): [init_reqids_port() done]");
1678
1679
    /* set up pcon as a transmission channel to the parent */
1680
  pcon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
1681
  MDBGLOG("port","handle_port(): [pcon created]");
1682
1683
  pcon->trans_data_in = &parent_data_in_port;
1684
  pcon->header_size = 28;
1685
  rv = trans_attach(pcon, sck);
1686
1687
  MDBGLOG("port","handle_port(): [pcon attached] (rv = %d; sck = %d)",rv,sck);
1688
1689
  pcon->sck = sck;
1690
  port->ccon = pcon;
1691
1692
  TC_MUTEX_UNLOCK((tc_p)mutex_port);
1693
  TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1694
1695
  if (rv == 0) {
1696
    tbus fdm = -1;
1697
    tbus fds = -1;
1698
    char * sname = "/var/run/ttyRDP";
1699
1700
    //MDBGLOG("port","handle_port(): (about to lock mutex_pcon_port and mutex_port) [1.5]");
1701
1702
    TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1703
    TC_MUTEX_LOCK((tc_p)mutex_port);
1704
1705
    //MDBGLOG("port","handle_port(): (mutex_pcon_port and mutex_port locked) [2]");
1706
1707
    /* add pcon to the set of monitored channels */
1708
    if (pcon != NULL && pcon->sck > 0) {
1709
      objs[num_objs] = pcon->sck;
1710
      num_objs++;
1711
      check_parent = 1;
1712
    }
1713
1714
    //MDBGLOG("port","handle_port(): [3]");
1715
1716
    //g_snprintf(node_buf, sizeof(node_buf) - 1, node_base, node_num);
1717
    //g_sprintf(node_buf, node_base, node_num);
1718
    s = g_tcp_local_socket();
1719
1720
    //MDBGLOG("port","handle_port(): [4]");
1721
1722
    g_file_delete(sname);
1723
    fdm = open("/dev/ptmx", O_RDWR);
1724
    grantpt(fdm);
1725
    unlockpt(fdm);
1726
    sname = ptsname(fdm);
1727
1728
    s = fdm;
1729
1730
    //MDBGLOG("port","handle_port(): [5]");
1731
    if (s < 0) {
1732
      MDBGLOG("port", "ERROR\t[%s()]: failed to set up pseudo tty", __func__);
1733
    }
1734
    else {
1735
      //MDBGLOG("port","handle_port(): [7]");
1736
      MDBGLOG("port", "INFO\t[%s()]: about to call g_create_wait_obj_from_socket(%d, 0)", __func__, s);
1737
      port->fd = g_create_wait_obj_from_socket(s, 0);
1738
1739
      // add the appropriate file descriptor to the set of monitored channels
1740
      if (port->fd > 0) {
1741
	objs[num_objs] = port->fd;
1742
	num_objs++;
1743
	check_device = 1;
1744
	  MDBGLOG("port","handle_port(): added port->fd = \"%d\"",port->fd);
1745
	}
1746
    }
1747
1748
    TC_MUTEX_UNLOCK((tc_p)mutex_port);
1749
    TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1750
1751
    MDBGLOG("port","INFO\t[%s()]: pseudo tty = \"%s\", port->fd = %d, sck = %d, port->dos_name = %s",__func__,sname,port->fd,sck,((port->dos_name == NULL) ? "" : port->dos_name));
1752
1753
    cb.port = port;
1754
    MDBGLOG("port","INFO\t[%s()]: calling rdp_addport()...", __func__);
1755
    rdp_addport(&cb);
1756
1757
    /* monitor the above channels for input and respond appropriately */
1758
    if (num_objs > 0 && objs[0] > -1) {
1759
1760
      TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
1761
      TC_MUTEX_LOCK((tc_p)mutex_port);
1762
1763
      //MDBGLOG("port","handle_port(): (mutex_pcon_port and mutex_port locked) [3]");
1764
1765
      largs.port = port;
1766
      largs.pcon = pcon;
1767
      largs.objs[0] = objs[0];
1768
      largs.objs[1] = objs[1];
1769
      largs.num_objs = num_objs;
1770
      largs.timeout = timeout;
1771
      largs.check_parent = check_parent;
1772
      largs.check_device = check_device;
1773
1774
      TC_MUTEX_UNLOCK((tc_p)mutex_port);
1775
      TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
1776
1777
      //MDBGLOG("port","handle_port(): (mutex_pcon_port and mutex_port unlocked) [3]");
1778
1779
      if (objs != NULL && num_objs > 0 && (check_parent > 0 || check_device > 0)) {
1780
1781
	tc_t lattr;
1782
	g_memset(&lattr,0,sizeof(tc_t));
1783
	tc_threadattr_init(&lattr);
1784
	tc_threadattr_setdetachstate(&lattr, TC_CREATE_JOINABLE);
1785
1786
	MDBGLOG("port","handle_port(): initializing threads...");
1787
1788
	TC_THREAD_INIT_FULL(&(thread_parent.thread),(const tc_threadattr_t *)&lattr,&loop_parent_port,&largs);
1789
	TC_THREAD_INIT_FULL(&(thread_device.thread),(const tc_threadattr_t *)&lattr,&loop_device_port,&largs);
1790
1791
	MDBGLOG("port","handle_port(): initialized.");
1792
	MDBGLOG("port","handle_port(): waiting to join threads...");
1793
1794
	TC_THREAD_JOIN(thread_parent.thread, NULL);
1795
	TC_THREAD_JOIN(thread_device.thread, NULL);
1796
1797
	MDBGLOG("port","handle_port(): joined.");
1798
      }
1799
    }
1800
  }
1801
1802
  MDBGLOG("port","handle_port(): done.");
1803
1804
  return rv;
1805
}
1806
1807
1808
/*****************************************************************************/
1809
static int APP_CC get_reqid_port(int * inarg) {
1810
  int rv = 0;
1811
  if (inarg == NULL) {
1812
    rv = -1;
1813
  }
1814
  else {
1815
    *inarg = -1;
1816
    //TC_MUTEX_LOCK((tc_p)mutex_reqid);
1817
    for (rv = 1; rv < MAX_REQID; rv++) {
1818
      if (g_reqids[rv].opid == -1) {
1819
	*inarg = rv;
1820
	g_reqids[rv].opid = rv;
1821
	TC_MUTEX_INIT((tc_p)&(g_reqids[rv].mutex),NULL);
1822
	TC_COND_CREATE((tc_p)&(g_reqids[rv].cv),NULL);
1823
	break;
1824
      }
1825
    }
1826
    //TC_MUTEX_UNLOCK((tc_p)mutex_reqid);
1827
  }
1828
  return rv;
1829
}
1830
1831
static int APP_CC free_reqid_port(int inarg) {
1832
  int rv = 0;
1833
  if (inarg < 0 || inarg > MAX_REQID) {
1834
    rv = -1;
1835
  }
1836
  else if (g_reqids[inarg].opid > -1 && g_reqids[inarg].opid <= MAX_REQID) {
1837
    TC_MUTEX_LOCK((tc_p)mutex_reqid);
1838
    TC_MUTEX_DEINIT(&(g_reqids[inarg].mutex));
1839
    TC_COND_DEINIT(&(g_reqids[inarg].cv));
1840
    g_memset(&(g_reqids[inarg]),0,sizeof(callback));
1841
    g_reqids[inarg].opid = -1;
1842
    TC_MUTEX_UNLOCK((tc_p)mutex_reqid);
1843
  }
1844
  return rv;
1845
}
1846
1847
static int APP_CC init_reqids_port() {
1848
  int rv = 0;
1849
  MDBGLOG("port","init_reqids_port(): started");
1850
  //TC_MUTEX_LOCK((tc_p)mutex_reqid);
1851
  g_memset((callback *)g_reqids,0,sizeof(callback)*MAX_REQID);
1852
  for (rv = 0; rv < MAX_REQID; rv++) {
1853
    g_reqids[rv].opid = -1;
1854
  }
1855
  //TC_MUTEX_UNLOCK((tc_p)mutex_reqid);
1856
  MDBGLOG("port","init_reqids_port(): done.");
1857
  rv = 0;
1858
  return rv;
1859
}
1860
1861
static int APP_CC retrieve_reqid_port(int uniqid) {
1862
  int rv = -1;
1863
  int found = 0;
1864
1865
  for (rv = 0; rv < MAX_REQID; rv++) {
1866
    if (g_reqids[rv].uniqid == uniqid) {
1867
      found = 1;
1868
      break;
1869
    }
1870
  }
1871
  if (found < 1) {
1872
    rv = -1;
1873
  }
1874
1875
  return rv;
1876
}
1877
1878
static int APP_CC get_mutex_port(int reqid, tc_p * inarg) {
1879
  int rv = 0;
1880
1881
  if (reqid >= 0 && reqid < MAX_REQID) {
1882
    //TC_MUTEX_LOCK((tc_p)mutex_reqid);
1883
    *inarg = (tc_p)&(g_reqids[reqid].mutex);
1884
    //TC_MUTEX_UNLOCK((tc_p)mutex_reqid);
1885
  }
1886
  else {
1887
    rv = -1;
1888
  }
1889
  return rv;
1890
}
1891
1892
static int APP_CC get_cv_port(int reqid, tc_p * inarg) {
1893
  int rv = 0;
1894
  if (reqid >= 0 && reqid < MAX_REQID) {
1895
    //TC_MUTEX_LOCK((tc_p)mutex_reqid);
1896
    *inarg = (tc_p)&(g_reqids[reqid].cv);
1897
    //TC_MUTEX_UNLOCK((tc_p)mutex_reqid);
1898
  }
1899
  else {
1900
    rv = -1;
1901
  }
1902
  return rv;
1903
}
1904
1905
static char * APP_CC rdpport_get_dircomponent(char * rv, const char * name) {
1906
  char * npos = (char *)NULL;
1907
1908
  if (name != NULL) {
1909
    npos = (char *)g_strrchr(name, (int)'/');
1910
    if (npos > 0) {
1911
      if (rv == NULL) {
1912
	rv = (char *)g_malloc(sizeof(char) * ((npos - name) + 1), 1);
1913
      }
1914
      g_strncpy(rv, name, (npos - name));
1915
    }
1916
  }
1917
1918
  return rv;
1919
}
1920
1921
/********************************************************/
1922
/*	refactor a filename into canonical form		*/
1923
/********************************************************/
1924
static void APP_CC rdpport_clean_fname(char * name) {
1925
        char * p = (char *)NULL;
1926
	char * p2 = (char *)NULL;
1927
        int l = 0;
1928
        int modified = 1;
1929
	const char forbidden[] = {'/', '[', ']', ':', '|', '<', '>', '+', '=', ';', ',', '?', 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
1930
1931
        if (name == NULL) {
1932
	  return;
1933
	}
1934
1935
        MDBGLOG("port","rdpport_clean_fname() [%s]:\n", name);
1936
1937
	while (modified) {
1938
		modified = 0;
1939
		if ((p=strstr(name,"/./"))) {
1940
			modified = 1;
1941
			while (*p) {
1942
				p[0] = p[2];
1943
				p++;
1944
			}
1945
			MDBGLOG("port", "\tclean 1 (/./) produced [%s]\n", name);
1946
		}
1947
		if ((p=strstr(name,"//"))) {
1948
			modified = 1;
1949
			while (*p) {
1950
				p[0] = p[1];
1951
				p++;
1952
			}
1953
			MDBGLOG("port", "\tclean 2 (//) produced [%s]\n", name);
1954
		}
1955
		if (strcmp(name,"/../")==0) {
1956
			modified = 1;
1957
			name[1] = 0;
1958
			MDBGLOG("port", "\tclean 3 (^/../$) produced [%s]\n", name);
1959
		}
1960
		if ((p=strstr(name,"/../"))) {
1961
			modified = 1;
1962
			for (p2 = (p > name ? p-1 : p); p2 > name; p2--) {
1963
				if (p2[0] == '/') {
1964
					break;
1965
				}
1966
			}
1967
			if (p2 > name) p2++;
1968
			while (*p2) {
1969
				p2[0] = p[3];
1970
				p2++;
1971
				p++;
1972
			}
1973
			MDBGLOG("port", "\tclean 4 (/../) produced [%s]\n", name);
1974
		}
1975
1976
                if (strcmp(name,"/..")==0) {
1977
                        modified = 1;
1978
                        name[1] = 0;
1979
                        MDBGLOG("port", "\tclean 5 (^/..$) produced [%s]\n", name);
1980
                }
1981
1982
                l = strlen(name);
1983
                p = l>=3?(name+l-3):name;
1984
                if (strcmp(p,"/..")==0) {
1985
                        modified = 1;
1986
                        for (p2=p-1;p2>name;p2--) {
1987
                                if (p2[0] == '/') break;
1988
                        }
1989
                        if (p2==name) {
1990
                                p[0] = '/';
1991
                                p[1] = 0;
1992
                        } else {
1993
                                p2[0] = 0;
1994
                        }
1995
                        MDBGLOG("port", "\tclean 6 (/..) produced [%s]\n", name);
1996
                }
1997
1998
                l = strlen(name);
1999
                p = l>=2?(name+l-2):name;
2000
                if (strcmp(p,"/.")==0) {
2001
                        modified = 1;
2002
                        if (p == name) {
2003
                                p[1] = 0;
2004
                        } else {
2005
                                p[0] = 0;
2006
                        }
2007
                        MDBGLOG("port", "\tclean 7 (/.) produced [%s]\n", name);
2008
                }
2009
2010
                if (strncmp(p=name,"./",2) == 0) {
2011
                        modified = 1;
2012
                        do {
2013
                                p[0] = p[2];
2014
                        } while (*p++);
2015
                        MDBGLOG("port", "\tclean 8 (^./) produced [%s]\n", name);
2016
                }
2017
2018
                l = strlen(p=name);
2019
                if (l > 1 && p[l-1] == '/') {
2020
                        modified = 1;
2021
                        p[l-1] = 0;
2022
                        MDBGLOG("port", "\tclean 9 (/) produced [%s]\n", name);
2023
                }
2024
        }
2025
2026
        MDBGLOG("port","rdpport_clean_fname() done [%s].\n", name);
2027
}
2028
2029
static int APP_CC ntstatus_to_errcode(DWORD ntstat) {
2030
  int retstat = 0;
2031
2032
  switch (ntstat) {
2033
	case 0:
2034
	  retstat = 0;
2035
	  break;
2036
	case STATUS_ACCESS_DENIED:
2037
	case STATUS_ACCESS_VIOLATION:
2038
	case STATUS_NETWORK_ACCESS_DENIED:
2039
	case STATUS_UNSUCCESSFUL:
2040
	  retstat = -EACCES;
2041
	  break;
2042
	case STATUS_GUARD_PAGE_VIOLATION:
2043
	case STATUS_INVALID_PARAMETER:
2044
	case STATUS_BAD_DEVICE_TYPE:
2045
	case STATUS_BAD_NETWORK_NAME:
2046
	case STATUS_INVALID_VOLUME_LABEL:
2047
	case STATUS_BAD_TOKEN_TYPE:
2048
	case STATUS_INVALID_GROUP_ATTRIBUTES:
2049
	case STATUS_BAD_MASTER_BOOT_RECORD:
2050
	case STATUS_INVALID_OPLOCK_PROTOCOL:
2051
	case STATUS_INVALID_INFO_CLASS:
2052
	case STATUS_INVALID_DEVICE_REQUEST:
2053
	case STATUS_INVALID_SYSTEM_SERVICE:
2054
	case STATUS_ILLEGAL_INSTRUCTION:
2055
	case STATUS_INVALID_LOCK_SEQUENCE:
2056
	case STATUS_INVALID_VIEW_SIZE:
2057
	case STATUS_INVALID_FILE_FOR_SECTION:
2058
	case STATUS_INVALID_DISPOSITION:
2059
	case STATUS_INVALID_UNWIND_TARGET:
2060
	case STATUS_INVALID_PORT_ATTRIBUTES:
2061
	case STATUS_INVALID_PARAMETER_MIX:
2062
	case STATUS_OBJECT_NAME_INVALID:
2063
	case STATUS_INVALID_VARIANT:
2064
	case STATUS_POWER_STATE_INVALID:
2065
	case STATUS_INVALID_DEVICE_OBJECT_PARAMETER:
2066
	case STATUS_INVALID_BLOCK_LENGTH:
2067
	  retstat = -EINVAL;
2068
	  break;
2069
#ifdef ENOMEDIUM
2070
	case STATUS_NO_MEDIA_IN_DEVICE:
2071
	case STATUS_UNRECOGNIZED_MEDIA:
2072
	  retstat = -ENOMEDIUM;
2073
	  break;
2074
#endif
2075
	case STATUS_SHARING_VIOLATION:
2076
	case STATUS_FILE_LOCK_CONFLICT:
2077
	case STATUS_LOCK_NOT_GRANTED:
2078
	case STATUS_SHARING_PAUSED:
2079
	case STATUS_SHARED_POLICY:
2080
	case STATUS_NOT_LOCKED:
2081
	case STATUS_PIPE_BUSY:
2082
	case STATUS_CONNECTION_IN_USE:
2083
	case STATUS_WAIT_FOR_OPLOCK:
2084
	  retstat = -EBUSY;
2085
	  break;
2086
	case STATUS_LOGON_FAILURE:
2087
	case STATUS_ACCOUNT_RESTRICTION:
2088
	case STATUS_ILL_FORMED_PASSWORD:
2089
	case STATUS_PASSWORD_RESTRICTION:
2090
	case STATUS_INVALID_LOGON_HOURS:
2091
	case STATUS_INVALID_WORKSTATION:
2092
	case STATUS_PASSWORD_EXPIRED:
2093
	case STATUS_ACCOUNT_DISABLED:
2094
	case STATUS_WRONG_PASSWORD:
2095
	case STATUS_SECTION_PROTECTION:
2096
	case STATUS_PRIVILEGE_NOT_HELD:
2097
	case STATUS_PRIVILEGED_INSTRUCTION:
2098
	case STATUS_PASSWORD_MUST_CHANGE:
2099
	case STATUS_ACCOUNT_LOCKED_OUT:
2100
	case STATUS_RESOURCE_NOT_OWNED:
2101
	case STATUS_LICENSE_VIOLATION:
2102
	case STATUS_LICENSE_QUOTA_EXCEEDED:
2103
	case STATUS_EVALUATION_EXPIRATION:
2104
	case STATUS_COPY_PROTECTION_FAILURE:
2105
	case STATUS_SMARTCARD_WRONG_PIN:
2106
	case STATUS_SMARTCARD_CARD_BLOCKED:
2107
	case STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED:
2108
	case STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT:
2109
	case STATUS_ACCESS_DISABLED_BY_POLICY_PATH:
2110
	case STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER:
2111
	case STATUS_ACCESS_DISABLED_BY_POLICY_OTHER:
2112
	case STATUS_CSS_AUTHENTICATION_FAILURE:
2113
	case STATUS_CSS_KEY_NOT_PRESENT:
2114
	case STATUS_CSS_KEY_NOT_ESTABLISHED:
2115
	case STATUS_INSUFFICIENT_LOGON_INFO:
2116
	  retstat = -EPERM;
2117
	  break;
2118
	case STATUS_DEVICE_DOES_NOT_EXIST:
2119
	case STATUS_DEVICE_NOT_CONNECTED:
2120
	case STATUS_DEVICE_POWER_FAILURE:
2121
	case STATUS_DEVICE_REMOVED:
2122
	case STATUS_PLUGPLAY_NO_DEVICE:
2123
	case STATUS_VOLUME_DISMOUNTED:
2124
	case STATUS_NOINTERFACE:
2125
	case STATUS_PARTITION_FAILURE:
2126
	  retstat = -ENODEV;
2127
	  break;
2128
	case STATUS_NO_MORE_FILES:
2129
	case STATUS_OBJECT_NAME_NOT_FOUND:
2130
	case STATUS_NOT_FOUND:
2131
	case STATUS_INVALID_PLUGPLAY_DEVICE_PATH:
2132
	case STATUS_NO_SUCH_FILE:
2133
	case STATUS_NETWORK_NAME_DELETED:
2134
	case STATUS_FILE_IS_OFFLINE:
2135
	case STATUS_MOUNT_POINT_NOT_RESOLVED:
2136
	  retstat = -ENOENT;
2137
	  break;
2138
	case STATUS_LOGON_SESSION_EXISTS:
2139
	case STATUS_DUPLICATE_NAME:
2140
	case STATUS_ALIAS_EXISTS:
2141
	case STATUS_ADDRESS_ALREADY_EXISTS:
2142
	case STATUS_DUPLICATE_OBJECTID:
2143
	case STATUS_OBJECTID_EXISTS:
2144
	  retstat = -EEXIST;
2145
	  break;
2146
	case STATUS_WRONG_VOLUME:
2147
	  retstat = -EXDEV;
2148
	  break;
2149
	case STATUS_BUFFER_TOO_SMALL:
2150
	case STATUS_SECTION_TOO_BIG:
2151
	case STATUS_SYSTEM_HIVE_TOO_LARGE:
2152
	  retstat = -E2BIG;
2153
	  break;
2154
	case STATUS_MEMORY_NOT_ALLOCATED:
2155
	case STATUS_NO_MEMORY:
2156
	case STATUS_INSUFFICIENT_RESOURCES:
2157
	case STATUS_INSUFF_SERVER_RESOURCES:
2158
	  retstat = -ENOMEM;
2159
	  break;
2160
	case STATUS_INVALID_HANDLE:
2161
	case STATUS_FILE_INVALID:
2162
	case STATUS_INVALID_PORT_HANDLE:
2163
	case STATUS_FILE_DELETED:
2164
	case STATUS_FILE_CLOSED:
2165
	case STATUS_FILE_CORRUPT_ERROR:
2166
	case STATUS_USER_MAPPED_FILE:
2167
	case STATUS_NOT_A_REPARSE_POINT:
2168
	case STATUS_DIRECTORY_IS_A_REPARSE_POINT:
2169
	case STATUS_FILE_NOT_ENCRYPTED:
2170
	case STATUS_FILE_ENCRYPTED:
2171
	case STATUS_CORRUPT_SYSTEM_FILE:
2172
	case STATUS_HANDLE_NOT_CLOSABLE:
2173
	  retstat = -EBADF;
2174
	  break;
2175
	case STATUS_FILES_OPEN:
2176
	  retstat = -EMFILE;
2177
	  break;
2178
	case STATUS_TOO_MANY_OPENED_FILES:
2179
	  retstat = -ENFILE;
2180
	  break;
2181
	case STATUS_PIPE_NOT_AVAILABLE:
2182
	case STATUS_INVALID_PIPE_STATE:
2183
	case STATUS_PIPE_BROKEN:
2184
	case STATUS_PIPE_EMPTY:
2185
	  retstat = -EPIPE;
2186
	  break;
2187
	case STATUS_DISK_FULL:
2188
	case STATUS_NO_LOG_SPACE:
2189
	case STATUS_LOG_FILE_FULL:
2190
	case STATUS_NO_SPOOL_SPACE:
2191
	case STATUS_PRINT_QUEUE_FULL:
2192
	case STATUS_DESTINATION_ELEMENT_FULL:
2193
	  retstat = -ENOSPC;
2194
	  break;
2195
	case STATUS_MEDIA_WRITE_PROTECTED:
2196
	  retstat = -EROFS;
2197
	  break;
2198
	case STATUS_DIRECTORY_NOT_EMPTY:
2199
	  retstat = -ENOTEMPTY;
2200
	  break;
2201
	case STATUS_RETRY:
2202
	  retstat = -EAGAIN;
2203
	  break;
2204
	case STATUS_OBJECT_PATH_NOT_FOUND:
2205
	case STATUS_NOT_A_DIRECTORY:
2206
	  retstat = -ENOTDIR;
2207
	  break;
2208
	case STATUS_FILE_IS_A_DIRECTORY:
2209
	  retstat = -EISDIR;
2210
	  break;
2211
	case STATUS_UNEXPECTED_IO_ERROR:
2212
	case STATUS_IO_PRIVILEGE_FAILED:
2213
	case STATUS_DEVICE_NOT_READY:
2214
	case STATUS_IO_DEVICE_ERROR:
2215
	case STATUS_OPEN_FAILED:
2216
	case STATUS_REPLY_MESSAGE_MISMATCH:
2217
	case STATUS_LOST_WRITEBEHIND_DATA:
2218
	  retstat = -EIO;
2219
	  break;
2220
	case STATUS_NOT_SUPPORTED:
2221
	case STATUS_ILLEGAL_FUNCTION:
2222
	case STATUS_WMI_NOT_SUPPORTED:
2223
	  retstat = -EOPNOTSUPP;
2224
	  break;
2225
	case STATUS_PIPE_DISCONNECTED:
2226
	case STATUS_CONNECTION_ABORTED:
2227
	case STATUS_CONNECTION_DISCONNECTED:
2228
	case STATUS_CONNECTION_RESET:
2229
	  retstat = -ECONNRESET;
2230
	  break;
2231
	default:
2232
	  break;
2233
  }
2234
2235
  return retstat;
2236
}
2237
2238
void * rdp_addport(void * inarg) {
2239
    callback * cbdata = (callback *)inarg;
2240
    int len = 0;
2241
    tbus fd = 0;
2242
    rdpport_t * port = (rdpport_t *)NULL;
2243
    struct cn_msg * data = (struct cn_msg *)NULL;
2244
    //rdp_socket_msg * rdpmsg = (rdp_socket_msg *)NULL;
2245
    void * rdata = (void *)NULL;
2246
    struct rdp_irq_data * rirq = (struct rdp_irq_data *)NULL;
2247
    unsigned char tbuf[512];
2248
2249
    MDBGLOG("port","INFO\t[%s()]: called (inarg = 0x%p)", __func__, inarg);
2250
2251
    g_memset(tbuf, 0x00, sizeof(tbuf));
2252
    fd = (cbdata != NULL && cbdata->port != NULL) ? cbdata->port->fd : -1;
2253
    if (fd < 0) {
2254
      MDBGLOG("port","ERROR\t[%s()]: fd = %d",__func__,fd);
2255
      goto end;
2256
    }
2257
2258
    port = cbdata->port;
2259
2260
  end:;
2261
    MDBGLOG("port","INFO\t[%s()]: done.", __func__);
2262
}
2263
2264
static void * rdp_irq_callback(void * inarg) {
2265
    callback * cbdata = (callback *)inarg;
2266
    int rv = 0;
2267
    int len = 0;
2268
    int olen = 0;
2269
    int reqid = 0;
2270
    int uniqid = 0;
2271
    int size = 0;
2272
    int fhandle = 0;
2273
    int qsize = 0;
2274
    int cid = 0;
2275
    tbus fd = 0;
2276
    tc_p lmutex = 0;
2277
    int rdpport_opcode = 0x00000000;
2278
    unsigned char * odata = (unsigned char *)NULL;
2279
    unsigned char * tp = (unsigned char *)NULL;
2280
    uint32_t crc32 = 0;
2281
    const uint32_t magic = RDP_PACKET_MAGIC;
2282
    uint32_t device_id = 0;
2283
    uint32_t * p_crc32 = (uint32_t *)NULL;
2284
    char * p = (char *)p;
2285
    rdpport_t * port = (rdpport_t *)NULL;
2286
    struct cn_msg * data = (struct cn_msg *)NULL;
2287
    //rdp_socket_msg * rdpmsg = (rdp_socket_msg *)NULL;
2288
    void * rdata = (void *)NULL;
2289
    struct rdp_irq_data * rirq = (struct rdp_irq_data *)NULL;
2290
    unsigned char tbuf[512];
2291
2292
    MDBGLOG("port","INFO\t[%s()]: called",__func__);
2293
2294
    g_memset(tbuf, 0, sizeof(tbuf));
2295
    fd = (cbdata != NULL && cbdata->port != NULL) ? cbdata->port->fd : -1;
2296
    if (fd < 0) {
2297
      MDBGLOG("port","ERROR\t[%s()]: fd = %d",__func__,fd);
2298
      rv = -EINVAL;
2299
      goto end;
2300
    }
2301
2302
    if (g_stop) {
2303
      goto end;
2304
    }
2305
2306
    port = cbdata->port;
2307
    reqid = cbdata->opid;
2308
    uniqid = cbdata->uniqid;
2309
    fhandle = cbdata->FileId;
2310
    cid = cbdata->CompletionId;
2311
2312
    qsize = 1;
2313
    MDBGLOG("port","INFO\t[%s()]: qsize = %d", __func__, qsize);
2314
2315
    get_mutex_port(reqid, &lmutex);
2316
2317
    if (qsize > 0) {
2318
      struct trans * lpcon = (struct trans *)NULL;
2319
      tc_p llmutex = (tc_p)NULL;
2320
      tc_p llcv = (tc_p)NULL;
2321
      uint32_t lreqid		= 0x00000000;
2322
      uint32_t luniqid		= 0x00000000;
2323
      uint32_t obuflen		= 0x00000000;
2324
      uint64_t offset		= 0x0000000000000000;
2325
      BYTE * obuf = (BYTE *)NULL;
2326
      LOCAL_STREAM(s);
2327
2328
      rdpport_opcode = RDPPORT_READ;
2329
      size = 0;
2330
      lreqid = reqid;
2331
      llmutex = lmutex;
2332
      luniqid = lreqid;
2333
      TC_MUTEX_LOCK((tc_p)llmutex);
2334
2335
      get_cv_port(lreqid, &llcv);
2336
      cbdata = &(g_reqids[lreqid]);
2337
      obuflen = sizeof(char) * qsize;
2338
      obuf = (BYTE *)g_malloc(cbdata->length + 1, 1);
2339
      cbdata->length = obuflen;
2340
      cbdata->userdata = (void *)obuf;
2341
      cbdata->flags = CBFLAG_PORT | CBFLAG_MUTEX | CBFLAG_FINAL;
2342
      cbdata->opid = lreqid;
2343
      cbdata->CompletionId = luniqid;
2344
      cbdata->uniqid = luniqid;
2345
      cbdata->port = port;
2346
      cbdata->FileId = fhandle;
2347
      cbdata->opcode = rdpport_opcode;
2348
      cbdata->trans = port->ccon;
2349
      cbdata->port = port;
2350
2351
      MDBGLOG("port","INFO\t[%s()]: &(cbdata->mutex) = \"%p\"; llmutex = \"%p\"", __func__, &(cbdata->mutex), (void *)llmutex);
2352
      MDBGLOG("port","INFO\t[%s()]: &(cbdata->cv) = \"%p\"; llcv = \"%p\"", __func__, &(cbdata->cv), (void *)llcv);
2353
2354
      TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
2355
      lpcon = port->ccon;
2356
      lpcon->callback_data = cbdata;
2357
      s = trans_get_out_s(lpcon, MAX_STREAM);
2358
      out_uint32_le(s, magic);
2359
      out_uint32_le(s, rdpport_opcode);
2360
      out_uint32_le(s, (size + sizeof(obuflen) + sizeof(offset)));
2361
      out_uint32_le(s, device_id);
2362
      out_uint32_le(s, fhandle);
2363
      out_uint32_le(s, luniqid);
2364
      p_crc32 = s_get_pos(s);
2365
      out_uint32_le(s, crc32);
2366
      p = (char *)s_get_pos(s);
2367
      out_uint32_le(s, obuflen);
2368
      out_uint64_le(s, offset);
2369
      s_mark_end(s);
2370
      size = s->end - s->data;
2371
      if ((s->end - p) > 0) {
2372
	*p_crc32 = Crc32_ComputeBuf((uint32_t)0, (void *)p, (size_t)(s->end - p));
2373
      }
2374
2375
      MDBGLOG("port"," ** %s (read): sending [g_fd = %d, fhandle = %d, lreqid = %d, cbdata->CompletionId = %d, cbdata->uniqid = %d, cbdata->opid = %d]", __func__, g_fd, fhandle, lreqid, cbdata->CompletionId, cbdata->uniqid, cbdata->opid);
2376
      trans_force_write(lpcon);
2377
      g_memset(s->data,0,MAX_STREAM);
2378
      TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
2379
      MDBGLOG("port","sent.");
2380
2381
      MDBGLOG("port","INFO\t[%s()]: entering g_obj_wait loop:",__func__);
2382
      tc_cond_wait((tc_p)llcv, (tc_p)llmutex);
2383
      MDBGLOG("port","INFO\t[%s()]: exiting g_obj_wait loop.",__func__);
2384
2385
      olen = cbdata->length;
2386
      odata = (unsigned char *)(cbdata->userdata);
2387
2388
      TC_MUTEX_UNLOCK((tc_p)llmutex);
2389
    }
2390
2391
    MDBGLOG("port","INFO\t[%s()]: olen = %d; odata = \"%s\"",__func__,olen,odata);
2392
2393
    data = (struct cn_msg *)tbuf;
2394
    //rdpmsg = (rdp_socket_msg *)(data->data);
2395
    //rdata = (void *)(&(rdpmsg->data));
2396
    rirq = rdata;
2397
    //data->id.idx = CN_TEST_IDX;
2398
    //data->id.val = CN_TEST_VAL;
2399
    //data->seq = 0;
2400
    //data->ack = 0;
2401
    //data->len = sizeof(rdp_socket_msg) + sizeof(struct rdp_irq_data) + olen;
2402
    //rdpmsg->len = sizeof(struct rdp_irq_data) + olen;
2403
    //rdpmsg->type = RDP_M_ASYNC | RDP_M_RXFULL;
2404
    rirq->device_id = cbdata->port->device_id;
2405
    rirq->rx_len = olen;
2406
    if (olen > 0 && odata != NULL) {
2407
      g_memcpy(rirq->rx_buf, odata, olen);
2408
    }
2409
    //len = socket_send(fd, data);
2410
2411
    if (!g_stop) {
2412
      struct trans * pcon = (struct trans *)NULL;
2413
      tc_p lmutex = (tc_p)NULL;
2414
      tc_p lcv = (tc_p)NULL;
2415
      uint32_t cmd		= 0x00000000;
2416
      uint32_t ibuflen		= 0x00000000;
2417
      uint32_t obuflen		= 0x00000000;
2418
      uint32_t * mask		= (uint32_t *)NULL;
2419
      BYTE * ibuf = (BYTE *)NULL;
2420
      BYTE * obuf = (BYTE *)NULL;
2421
      LOCAL_STREAM(s);
2422
2423
      fhandle = cbdata->FileId;
2424
      mask = (uint32_t *)g_malloc(sizeof(uint32_t), 1);
2425
      *mask = cbdata->mask;
2426
2427
      TC_MUTEX_LOCK((tc_p)mutex_portop);
2428
      get_reqid_port(&reqid);
2429
      get_mutex_port(reqid, &lmutex);
2430
      TC_MUTEX_LOCK((tc_p)lmutex);
2431
      TC_MUTEX_UNLOCK((tc_p)mutex_portop);
2432
2433
      cbdata = &(g_reqids[reqid]);
2434
2435
      rdpport_opcode = RDPPORT_IOCTL;
2436
      cmd = IOCTL_SERIAL_WAIT_ON_MASK;
2437
      ibuflen = 0;
2438
      ibuf = NULL;
2439
      obuflen = sizeof(ULONG);
2440
      size = 0;
2441
      uniqid = reqid;
2442
2443
      cbdata->call = &rdp_irq_callback;
2444
      cbdata->cmd = cmd;
2445
      cbdata->flags = CBFLAG_PORT | CBFLAG_IRQ | CBFLAG_MUTEX | CBFLAG_FUNC | CBFLAG_CMD | CBFLAG_MASK;
2446
      cbdata->opid = reqid;
2447
      cbdata->CompletionId = uniqid;
2448
      cbdata->uniqid = uniqid;
2449
      cbdata->port = port;
2450
      cbdata->FileId = fhandle;
2451
      cbdata->opcode = rdpport_opcode;
2452
      cbdata->mask = *mask;
2453
2454
      crc32 = 0;
2455
2456
      TC_MUTEX_LOCK((tc_p)mutex_pcon_port);
2457
      g_irq_cb = cbdata;
2458
      g_irq_idx = reqid;
2459
      pcon = port->ccon;
2460
      pcon->callback_data = cbdata;
2461
      s = trans_get_out_s(pcon, MAX_STREAM);
2462
      out_uint32_le(s, magic);
2463
      out_uint32_le(s, rdpport_opcode);
2464
      out_uint32_le(s, size + (sizeof(cmd) + sizeof(ibuflen) + sizeof(obuflen) + ibuflen));
2465
      out_uint32_le(s, device_id);
2466
      out_uint32_le(s, fhandle);
2467
      out_uint32_le(s, uniqid);
2468
      p_crc32 = s_get_pos(s);
2469
      out_uint32_le(s, crc32);
2470
      p = (char *)s_get_pos(s);
2471
      out_uint32_le(s, cmd);
2472
      out_uint32_le(s, ibuflen);
2473
      out_uint32_le(s, obuflen);
2474
      s_mark_end(s);
2475
      size = s->end - s->data;
2476
      if ((s->end - p) > 0) {
2477
	*p_crc32 = Crc32_ComputeBuf(0, p, s->end - p);
2478
      }
2479
2480
      MDBGLOG("port"," ** %s (waitonmask): sending [g_fd = %d, fhandle = %d, reqid = %d, cbdata->CompletionId = %d, cbdata->uniqid = %d, cbdata->opid = %d, cbdata->cmd = 0x%8.8x]", __func__, g_fd, fhandle, reqid, cbdata->CompletionId, cbdata->uniqid, cbdata->opid, cbdata->cmd);
2481
      trans_force_write(pcon);
2482
      TC_MUTEX_UNLOCK((tc_p)lmutex);
2483
      g_memset(s->data,0,MAX_STREAM);
2484
      MDBGLOG("port","sent.");
2485
      TC_MUTEX_UNLOCK((tc_p)mutex_pcon_port);
2486
      goto end;
2487
    }
2488
2489
    cbdata->userdata = NULL;
2490
    TC_MUTEX_UNLOCK((tc_p)lmutex);
2491
    free_reqid_port(reqid);
2492
2493
  end:;
2494
    MDBGLOG("port", "INFO\t[%s()]: done.", __func__);
2495
    tc_thread_exit(NULL);
2496
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/rdpport_defs.h (+8 lines)
Line 0    Link Here 
1
#ifndef	XRDPPORT_DEFS
2
#define XRDPPORT_DEFS
3
4
static const char * cmdarray[] = CMD_TO_STRING_ARRAY_DEF;
5
6
#define RDPUARTCMD(x) (cmdarray[(x & 0x1f)])
7
8
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/rdpprint.c (+1477 lines)
Line 0    Link Here 
1
/*
2
 *
3
 * Client-side printer redirection over RDP
4
 *
5
 */
6
7
#include "params.h"
8
9
#include <pthread.h>
10
#include <ctype.h>
11
#include <errno.h>
12
#include <fcntl.h>
13
#include <stdlib.h>
14
#include <stdio.h>
15
#include <string.h>
16
#include <termios.h>
17
#include <unistd.h>
18
#include <sys/types.h>
19
#include <sys/sysmacros.h>
20
21
#include "log.h"
22
#include "arch.h"
23
#include "parse.h"
24
#include "defines.h"
25
#include "rdpdr.h"
26
#include "rdpdr_methods.h"
27
#include "trans.h"
28
#include "devredir_defs.h"
29
#include "global.h"
30
#include "thread_calls.h"
31
#include "dbg.h"
32
33
static int g_fd = -1;
34
static rdpprint * g_printer = (rdpprint *)NULL;
35
36
static uint32_t pmagic = RDP_PACKET_MAGIC;
37
38
#ifndef MAX_REQID
39
#define MAX_REQID	25
40
#endif
41
static callback g_reqids[MAX_REQID];
42
43
#ifndef MAX_MUTEX
44
#define MAX_MUTEX	25
45
#endif
46
static tbus g_mutexes[MAX_MUTEX];
47
static pthread_cond_t g_condition_variables[MAX_MUTEX];
48
49
//tbus mutex_device;
50
extern tc_p g_mutex;
51
extern tc_p mut;
52
53
static tc_t g_mutex_pcon;
54
static tc_t g_mutex_print;
55
static tc_t g_mutex_device;
56
static tc_t g_mutex_parent;
57
static tc_t g_mutex_printop;
58
static tc_t g_mutex_reqid;
59
static tc_p mutex_pcon = (tc_p)NULL;
60
static tc_p mutex_print = (tc_p)NULL;
61
static tc_p mutex_parent = (tc_p)NULL;
62
static tc_p mutex_printop = (tc_p)NULL;
63
static tc_p mutex_reqid = (tc_p)NULL;
64
static tc_p mutex_device = (tc_p)NULL;
65
66
static int APP_CC rdpprint_open(tbus);
67
static int APP_CC rdpprint_open_args(tbus, uint32_t, uint32_t, uint32_t, uint32_t);
68
static int APP_CC rdpprint_release(tbus);
69
static int APP_CC rdpprint_ioctl(tbus, int, size_t, void *, size_t, void *);
70
71
static int APP_CC rdpprint_cycle(rdpprint *);
72
73
static int APP_CC get_reqid(int *);
74
static int APP_CC free_reqid(int);
75
static int APP_CC init_reqids(void);
76
static int APP_CC get_mutex(int, tc_p);
77
static int APP_CC get_cv(int, tc_p);
78
static int APP_CC ntstatus_to_errcode(DWORD);
79
80
extern int APP_CC get_RDPDR_HEADER(RDPDR_HEADER *, struct stream *);
81
extern int APP_CC get_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *, struct stream *);
82
extern int APP_CC get_DR_CREATE_RSP(DR_CREATE_RSP *, struct stream *);
83
extern int APP_CC get_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP *, struct stream *);
84
extern int APP_CC get_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *, struct stream *);
85
extern int APP_CC construct_RDPDR_HEADER(RDPDR_HEADER *);
86
extern int APP_CC construct_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *);
87
extern int APP_CC construct_DR_CREATE_RSP(DR_CREATE_RSP *);
88
extern int APP_CC construct_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *);
89
extern char * APP_CC ntstatus_string(uint32_t);
90
91
static int APP_CC parent_data_in(struct trans *);
92
93
/*
94
 *	printer open operation
95
 */
96
static int rdpprint_open(tbus fh) {
97
    int retstat = 0;
98
    struct stream * s = NULL;
99
    int idx = 0;
100
    struct trans * pcon = (struct trans *)NULL;
101
    int rdpprint_opcode = 0x00000000;
102
    int size = 0x00000000;
103
    rdpprint_data rdata;
104
    tbus lmutex = (tbus)NULL;
105
    tbus lcv = (tbus)NULL;
106
    callback * cbdata = NULL;
107
    uint32_t pflags = 0x00000000;
108
    uint32_t pshare = 0x00000000;
109
    uint32_t poptions = 0x00000000;
110
    uint32_t pattributes = 0x00000000;
111
    int reqid = -1;
112
    int uniqid = 0;
113
    uint32_t magic = 0;
114
    uint32_t crc32 = 0;
115
    uint32_t calc_crc32 = 0;
116
117
    MDBGLOG("print","\n\nrdpprint_open (fh=\"%d\")\n",fh);
118
119
    g_memset(&rdata,0,sizeof(rdpprint_data));
120
121
    tc_mutex_lock(mutex_printop);
122
    get_reqid(&reqid);
123
    get_mutex(reqid, &lmutex);
124
    tc_mutex_lock(lmutex);
125
    tc_mutex_unlock(mutex_printop);
126
127
    get_cv(reqid, &lcv);
128
    cbdata = &(g_reqids[reqid]);
129
130
    pflags = GENERIC_ALL;
131
    pshare |= (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
132
133
    rdpprint_opcode = RDPPRINT_OPEN;
134
    uniqid = reqid;
135
136
    tc_mutex_lock(mutex_pcon);
137
    pcon = g_printer->ccon;
138
    pcon->callback_data = cbdata;
139
    s = trans_get_out_s(pcon, MAX_STREAM);
140
    out_uint32_le(s, pmagic);
141
    out_uint32_le(s, rdpprint_opcode);
142
    out_uint32_le(s, size + 16);
143
    out_uint32_le(s, fh);
144
    out_uint32_le(s, uniqid);
145
    out_uint32_le(s, crc32);
146
    out_uint32_le(s, pflags);
147
    out_uint32_le(s, pshare);
148
    out_uint32_le(s, poptions);
149
    out_uint32_le(s, pattributes);
150
    s_mark_end(s);
151
    size = s->end - s->data;
152
153
    g_hexdump_file("/tmp/taskq_print_open.hexdump", s->data, size);
154
    MDBGLOG("print"," ** rdpprint_open(): sending [g_fd = %d]", g_fd);
155
    trans_force_write(pcon);
156
    g_memset(s->data,0,MAX_STREAM);
157
    DBGLOG("print","sent.");
158
    tc_mutex_unlock(mutex_pcon);
159
160
    DBGLOG("print","entering g_obj_wait loop:");
161
    tc_cond_wait(lcv, lmutex);
162
    DBGLOG("print","exiting g_obj_wait loop.");
163
164
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
165
    if (retstat < 0) {
166
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
167
      MDBGLOG("print","ERROR [rdpprint_open()]: \"%s\" (retstat = %d; cbdata->IoStatus.Fields.Sev = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
168
    }
169
170
    MDBGLOG("print","rdpprint_open(): done. (fh = %d; retstat = %d)",fh,retstat);
171
172
    tc_mutex_unlock(lmutex);
173
    free_reqid(reqid);
174
175
    return retstat;
176
}
177
178
static int rdpprint_open_args(tbus fh, uint32_t pflags, uint32_t pshare, uint32_t poptions, uint32_t pattributes) {
179
    int retstat = 0;
180
    struct stream * s = NULL;
181
    int idx = 0;
182
    struct trans * pcon = (struct trans *)NULL;
183
    int rdpprint_opcode = 0x00000000;
184
    int size = 0x00000000;
185
    rdpprint_data rdata;
186
    tbus lmutex = (tbus)NULL;
187
    tbus lcv = (tbus)NULL;
188
    callback * cbdata = NULL;
189
    int reqid = -1;
190
    int fhandle = 0;
191
    int uniqid = 0;
192
    uint32_t magic = 0;
193
    uint32_t crc32 = 0;
194
    uint32_t calc_crc32 = 0;
195
196
    MDBGLOG("print","\n\nrdpprint_open_args (fh = \"%d\"; pflags = 0x%8.8x; pshare  = 0x%8.8x; poptions = 0x%8.8x)\n",fh,pflags,pshare,poptions);
197
198
    g_memset(&rdata,0,sizeof(rdpprint_data));
199
200
    tc_mutex_lock(mutex_printop);
201
    get_reqid(&reqid);
202
    get_mutex(reqid, &lmutex);
203
    tc_mutex_lock(lmutex);
204
    tc_mutex_unlock(mutex_printop);
205
206
    get_cv(reqid, &lcv);
207
    cbdata = &(g_reqids[reqid]);
208
209
    rdpprint_opcode = RDPPRINT_OPEN;
210
    uniqid = reqid;
211
212
    tc_mutex_lock(mutex_pcon);
213
    pcon = g_printer->ccon;
214
    pcon->callback_data = cbdata;
215
    s = trans_get_out_s(pcon, MAX_STREAM);
216
    out_uint32_le(s, pmagic);
217
    out_uint32_le(s, rdpprint_opcode);
218
    out_uint32_le(s, size + 16);
219
    out_uint32_le(s, fhandle);
220
    out_uint32_le(s, uniqid);
221
    out_uint32_le(s, crc32);
222
    out_uint32_le(s, pflags);
223
    out_uint32_le(s, pshare);
224
    out_uint32_le(s, poptions);
225
    out_uint32_le(s, pattributes);
226
    s_mark_end(s);
227
    size = s->end - s->data;
228
229
    g_hexdump_file("/tmp/taskq_print_open_args.hexdump", s->data, size);
230
    MDBGLOG("print"," ** rdpprint_open_args(): sending [g_fd = %d]", g_fd);
231
    trans_force_write(pcon);
232
    g_memset(s->data,0,MAX_STREAM);
233
    DBGLOG("print","sent.");
234
    tc_mutex_unlock(mutex_pcon);
235
236
    DBGLOG("print","entering g_obj_wait loop:");
237
    tc_cond_wait(lcv, lmutex);
238
    DBGLOG("print","exiting g_obj_wait loop.");
239
240
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
241
    if (retstat < 0) {
242
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
243
      MDBGLOG("print","ERROR [rdpprint_open_args()]: \"%s\" (retstat = %d; cbdata->IoStatus.Fields.Sev = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
244
      fhandle = -1;
245
    }
246
247
    MDBGLOG("print","rdpprint_open_args(): done. (fh = %d; retstat = %d)",fh,retstat);
248
249
    tc_mutex_unlock(lmutex);
250
    free_reqid(reqid);
251
252
    return retstat;
253
}
254
255
/** Read data from an open file
256
 *
257
 * Read should return exactly the number of bytes requested except
258
 * on EOF or error, otherwise the rest of the data will be
259
 * substituted with zeroes.  An exception to this is when the
260
 * 'direct_io' mount option is specified, in which case the return
261
 * value of the read system call will reflect the return value of
262
 * this operation.
263
 *
264
 * Changed in version 2.2
265
 */
266
// I don't fully understand the documentation above -- it doesn't
267
// match the documentation for the read() system call which says it
268
// can return with anything up to the amount of data requested. nor
269
// with the fusexmp code which returns the amount of data also
270
// returned by read.
271
272
static int rdpprint_read_chunk(tbus fh, char * buf, size_t size) {
273
    int retstat = 0;
274
    int plen = 0;
275
    struct stream * s = NULL;
276
    int idx = 0;
277
    struct trans * pcon = (struct trans *)NULL;
278
    int rdpprint_opcode = 0x00000000;
279
    int reqid = -1;
280
    int uniqid = 0;
281
    tbus lmutex = (tbus)NULL;
282
    tbus lcv = (tbus)NULL;
283
    callback * cbdata = NULL;
284
    int mode = 0;
285
    size_t fsize = 0;
286
    uint32_t magic = 0;
287
    uint32_t crc32 = 0;
288
    uint32_t calc_crc32 = 0;
289
290
    tc_mutex_lock(mutex_printop);
291
    get_reqid(&reqid);
292
    get_mutex(reqid, &lmutex);
293
    tc_mutex_lock(lmutex);
294
    tc_mutex_unlock(mutex_printop);
295
296
    cbdata = &(g_reqids[reqid]);
297
    cbdata->userdata = buf;
298
299
    rdpprint_opcode = RDPPRINT_READ;
300
    uniqid = reqid;
301
302
    tc_mutex_lock(mutex_pcon);
303
    pcon = g_printer->ccon;
304
    pcon->callback_data = cbdata;
305
    s = trans_get_out_s(pcon, MAX_STREAM);
306
    out_uint32_le(s, pmagic);
307
    out_uint32_le(s, rdpprint_opcode);
308
    out_uint32_le(s, 4);
309
    out_uint32_le(s, fh);
310
    out_uint32_le(s, uniqid);
311
    out_uint32_le(s, crc32);
312
    out_uint32_le(s, size);
313
    s_mark_end(s);
314
    fsize = s->end - s->data;
315
    g_hexdump_file("/tmp/taskq_print_read_chunk_cmd.hexdump", s->data, fsize);
316
    trans_force_write(pcon);
317
    g_memset(s->data,0,sizeof(char)*MAX_STREAM);
318
    tc_mutex_unlock(mutex_pcon);
319
    DBGLOG("print","sent.");
320
321
    DBGLOG("print"," Entering wait loop...");
322
    get_cv(reqid,&lcv);
323
    tc_cond_wait(lcv,lmutex);
324
    DBGLOG("print"," Finished.");
325
326
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
327
    if (retstat < 0) {
328
      const char * nterr = (const char *)ntstatus_string(cbdata->IoStatus.Value);
329
      MDBGLOG("print","ERROR [rdpprint_read_chunk()]: \"%s\" (retstat = %d; cbdata->IoStatus.Value = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
330
      //retstat = 0;
331
    }
332
    else {
333
      retstat = cbdata->length;
334
    }
335
    g_hexdump_file("/tmp/taskq_print_read_chunk_result.hexdump", cbdata->userdata, cbdata->length);
336
    g_memset(cbdata,0,sizeof(callback));
337
338
    tc_mutex_unlock(lmutex);
339
    free_reqid(reqid);
340
341
    return retstat;
342
}
343
344
static int rdpprint_read(tbus fh, char * buf, size_t size) {
345
    #ifndef CHUNK_SIZE
346
    #define CHUNK_SIZE 4096
347
    #endif
348
    int retstat = 0;
349
    struct stream * s = NULL;
350
    int idx = 0;
351
    struct trans * pcon = (struct trans *)NULL;
352
    int rdpprint_opcode = 0x00000000;
353
    int reqid = -1;
354
    int uniqid = 0;
355
    tbus lmutex = (tbus)NULL;
356
    tbus lcv = (tbus)NULL;
357
    callback * cbdata = NULL;
358
    int mode = 0;
359
    int chunks = 0;
360
    char * tpos = NULL;
361
    off_t toffset = 0;
362
    size_t tsize = 0;
363
    uint64_t tally = 0;
364
365
    MDBGLOG("print","rdpprint_read(): fh = %d; size = %d",fh,size);
366
367
    chunks = (size == 0) ? 0 : 1;
368
    if (size > CHUNK_SIZE) {
369
      chunks = ((size % CHUNK_SIZE) == 0) ? size / CHUNK_SIZE : (size / CHUNK_SIZE) + 1;
370
    }
371
372
    for (idx = 0; idx < chunks; idx++) {
373
      tpos = buf + (idx * CHUNK_SIZE);
374
      toffset = 0;
375
      tsize = (idx == (chunks - 1) && (size % CHUNK_SIZE) != 0) ? size % CHUNK_SIZE : CHUNK_SIZE;
376
      retstat = rdpprint_read_chunk(fh,tpos,tsize);
377
      if (retstat < 0) {
378
	break;
379
      }
380
      else {
381
	tally += retstat;
382
      }
383
    }
384
    if (retstat > -1) {
385
      retstat = tally;
386
    }
387
388
    return retstat;
389
}
390
391
/** Write data to an open file
392
 *
393
 * Write should return exactly the number of bytes requested
394
 * except on error.  An exception to this is when the 'direct_io'
395
 * mount option is specified (see read operation).
396
 *
397
 * Changed in version 2.2
398
 */
399
static int rdpprint_write_chunk(tbus fh, const char * buf, size_t size) {
400
    int retstat = 0;
401
    struct stream * s = NULL;
402
    int idx = 0;
403
    int fsize = 0;
404
    struct trans * pcon = (struct trans *)NULL;
405
    int rdpprint_opcode = 0x00000000;
406
    int reqid = -1;
407
    int uniqid = 0;
408
    tbus lmutex = (tbus)NULL;
409
    tbus lcv = (tbus)NULL;
410
    callback * cbdata = NULL;
411
    uint32_t magic = 0;
412
    uint32_t crc32 = 0;
413
    uint32_t calc_crc32 = 0;
414
415
    tc_mutex_lock(mutex_printop);
416
    get_reqid(&reqid);
417
    get_mutex(reqid, &lmutex);
418
    tc_mutex_lock(lmutex);
419
    tc_mutex_unlock(mutex_printop);
420
421
    cbdata = &(g_reqids[reqid]);
422
    cbdata->userdata = (char *)buf;
423
424
    rdpprint_opcode = RDPPRINT_WRITE;
425
    uniqid = reqid;
426
427
    tc_mutex_lock(mutex_pcon);
428
    pcon = g_printer->ccon;
429
    pcon->callback_data = cbdata;
430
    s = trans_get_out_s(pcon, MAX_STREAM);
431
    out_uint32_le(s, pmagic);
432
    out_uint32_le(s, rdpprint_opcode);
433
    out_uint32_le(s, size);
434
    out_uint32_le(s, fh);
435
    out_uint32_le(s, uniqid);
436
    out_uint32_le(s, crc32);
437
    if (size > 0) {
438
      out_uint8a(s, buf, size);
439
    }
440
    s_mark_end(s);
441
    fsize = s->end - s->data;
442
    g_hexdump_file("/tmp/taskq_print_write_chunk_cmd.hexdump", s->data, fsize);
443
    trans_force_write(pcon);
444
    g_memset(s->data,0,sizeof(char)*MAX_STREAM);
445
    tc_mutex_unlock(mutex_pcon);
446
    DBGLOG("print","sent.");
447
448
    DBGLOG("print"," Entering wait loop...");
449
    get_cv(reqid,&lcv);
450
    tc_cond_wait(lcv,lmutex);
451
    DBGLOG("print"," Finished.");
452
453
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
454
    if (retstat < 0) {
455
      MDBGLOG("print","ERROR [rdpprint_write_chunk()]: retstat = %d; cbdata->IoStatus.Value = %d",retstat,cbdata->IoStatus.Value);
456
    }
457
    else {
458
      retstat = cbdata->length;
459
    }
460
    g_hexdump_file("/tmp/taskq_print_write_chunk_result.hexdump", cbdata->userdata, cbdata->length);
461
    g_memset(cbdata,0,sizeof(callback));
462
463
    tc_mutex_unlock(lmutex);
464
    free_reqid(reqid);
465
466
    return retstat;
467
}
468
469
static int rdpprint_write(tbus fh, const char * buf, size_t size) {
470
    #ifndef CHUNK_SIZE
471
    #define CHUNK_SIZE 4096
472
    #endif
473
    int retstat = 0;
474
    struct stream * s = NULL;
475
    int idx = 0;
476
    int fsize = 0;
477
    struct trans * pcon = (struct trans *)NULL;
478
    int rdpprint_opcode = 0x00000000;
479
    int reqid = -1;
480
    int uniqid = 0;
481
    tbus lmutex = (tbus)NULL;
482
    tbus lcv = (tbus)NULL;
483
    callback * cbdata = NULL;
484
    int mode = 0;
485
    int chunks = 0;
486
    char * tpos = (BYTE *)NULL;
487
    off_t toffset = 0;
488
    size_t tsize = 0;
489
    uint64_t tally = 0;
490
491
    chunks = (size == 0) ? 0 : 1;
492
    if (size > CHUNK_SIZE) {
493
      chunks = ((size % CHUNK_SIZE) == 0) ? size / CHUNK_SIZE : (size / CHUNK_SIZE) + 1;
494
    }
495
496
    for (idx = 0; idx < chunks; idx++) {
497
      tpos = (char *)buf + (idx * CHUNK_SIZE);
498
      tsize = (idx == (chunks - 1) && (size % CHUNK_SIZE) != 0) ? size % CHUNK_SIZE : CHUNK_SIZE;
499
      retstat = rdpprint_write_chunk(fh,tpos,tsize);
500
      if (retstat < 0) {
501
	break;
502
      }
503
      else {
504
	tally += retstat;
505
      }
506
    }
507
    if (retstat > -1) {
508
      retstat = tally;
509
    }
510
511
    return retstat;
512
}
513
514
/** Release an open file
515
 *
516
 */
517
static int rdpprint_release(tbus fh) {
518
    int retstat = 0;
519
    struct stream * s = NULL;
520
    int idx = 0;
521
    struct trans * pcon = (struct trans *)NULL;
522
    int rdpprint_opcode = 0x00000000;
523
    int size = 0x00000000;
524
    rdpprint_data rdata;
525
    int uniqid = 0;
526
    int reqid = -1;
527
    callback * cbdata = NULL;
528
    tbus lmut = (tbus)NULL;
529
    tbus lcv = (tbus)NULL;
530
    uint32_t magic = 0;
531
    uint32_t crc32 = 0;
532
    uint32_t calc_crc32 = 0;
533
534
    tc_mutex_lock(mutex_printop);
535
    get_reqid(&reqid);
536
    get_mutex(reqid,&lmut);
537
    tc_mutex_lock(lmut);
538
    tc_mutex_unlock(mutex_printop);
539
540
    MDBGLOG("print","\n\nrdpprint_release(fh=\"%d\")\n",fh);
541
    g_memset(&rdata,0,sizeof(rdpprint_data));
542
543
    rdpprint_opcode = RDPPRINT_CLOSE;
544
    uniqid = reqid;
545
    cbdata = &(g_reqids[reqid]);
546
    cbdata->FileId = fh;
547
548
    tc_mutex_lock(mutex_pcon);
549
    pcon = g_printer->ccon;
550
    pcon->callback_data = cbdata;
551
    s = trans_get_out_s(pcon, MAX_STREAM);
552
    out_uint32_le(s, pmagic);
553
    out_uint32_le(s, rdpprint_opcode);
554
    out_uint32_le(s, size);
555
    out_uint32_le(s, fh);
556
    out_uint32_le(s, uniqid);
557
    out_uint32_le(s, crc32);
558
    s_mark_end(s);
559
    size = s->end - s->data;
560
    MDBGLOG("print"," ** rdpprint_release(): sending [g_fd = %d]", g_fd);
561
    trans_force_write(pcon);
562
    DBGLOG("print","sent.");
563
    g_hexdump_file("/tmp/taskq_print_release.hexdump", s->data, size);
564
    g_memset(s->data,0,MAX_STREAM);
565
    tc_mutex_unlock(mutex_pcon);
566
567
    get_cv(reqid,&lcv);
568
    DBGLOG("print"," Waiting...");
569
    tc_cond_wait(lcv,lmut);
570
    DBGLOG("print"," Done.");
571
572
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
573
    if (retstat < 0) {
574
	char * nterr = ntstatus_string(cbdata->IoStatus.Value);
575
	//retstat = rdpprint_error("rdpprint_release lstat");
576
	MDBGLOG("print","ERROR [rdpprint_release()]: \"%s\" (retstat = %d)",nterr,retstat);
577
    }
578
579
    MDBGLOG("print","rdpprint_release(): done. ()");
580
581
    tc_mutex_unlock(lmut);
582
    free_reqid(reqid);
583
584
    return retstat;
585
}
586
587
/*
588
 *
589
 * Ioctl
590
 *
591
 */
592
static int rdpprint_ioctl(tbus fh, int cmd, size_t argslen, void * args, size_t buflen, void * buf) {
593
    int retstat = 0;
594
    struct stream * s = NULL;
595
    struct trans * pcon = (struct trans *)NULL;
596
    int rdpprint_opcode = 0x00000000;
597
    int size = 0x00000000;
598
    rdpprint_data rdata;
599
    tbus lmutex = (tbus)NULL;
600
    tbus lcv = (tbus)NULL;
601
    callback * cbdata = NULL;
602
    int reqid = -1;
603
    int uniqid = 0;
604
    uint32_t magic = 0;
605
    uint32_t crc32 = 0;
606
    uint32_t calc_crc32 = 0;
607
608
    tc_mutex_lock(mutex_printop);
609
    get_reqid(&reqid);
610
    get_mutex(reqid, &lmutex);
611
    tc_mutex_lock(lmutex);
612
    tc_mutex_unlock(mutex_printop);
613
614
    MDBGLOG("print","\n\nrdpprint_ioctl (fh=\"%d\"; argslen=\"%d\"; buflen=\"%d\")\n",fh,argslen,buflen);
615
616
    g_memset(&rdata,0,sizeof(rdpprint_data));
617
618
    get_cv(reqid, &lcv);
619
    cbdata = &(g_reqids[reqid]);
620
621
    rdpprint_opcode = RDPPRINT_IOCTL;
622
    uniqid = reqid;
623
    size = argslen;
624
625
    tc_mutex_lock(mutex_pcon);
626
    pcon = g_printer->ccon;
627
    pcon->callback_data = cbdata;
628
    s = trans_get_out_s(pcon, MAX_STREAM);
629
    out_uint32_le(s, pmagic);
630
    out_uint32_le(s, rdpprint_opcode);
631
    out_uint32_le(s, size + 4);
632
    out_uint32_le(s, fh);
633
    out_uint32_le(s, uniqid);
634
    out_uint32_le(s, crc32);
635
    out_uint32_le(s, cmd);
636
    if (argslen > 0) {
637
      out_uint8a(s, (char *)args, argslen);
638
    }
639
    s_mark_end(s);
640
    size = s->end - s->data;
641
642
    g_hexdump_file("/tmp/taskq_print_ioctl.hexdump", s->data, size);
643
    MDBGLOG("print"," ** rdpprint_ioctl(): sending [g_fd = %d; fh = %d; size = %d]", g_fd, argslen, size);
644
    trans_force_write(pcon);
645
    g_memset(s->data,0,MAX_STREAM);
646
    DBGLOG("print","sent.");
647
    tc_mutex_unlock(mutex_pcon);
648
649
    DBGLOG("print","entering g_obj_wait loop:");
650
    tc_cond_wait(lcv, lmutex);
651
    DBGLOG("print","exiting g_obj_wait loop.");
652
653
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
654
    if (retstat < 0) {
655
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
656
      MDBGLOG("print","ERROR [rdpprint_ioctl()]: \"%s\" (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR)",nterr);
657
    }
658
659
    DBGLOG("print","rdpprint_ioctl(): done.");
660
661
    tc_mutex_unlock(lmutex);
662
    free_reqid(reqid);
663
664
    return retstat;
665
}
666
667
668
/*****************************************************************************/
669
/*****		child process-related section				******/
670
/*****************************************************************************/
671
672
673
/*****************************************************************************/
674
static int APP_CC
675
parent_data_in(struct trans * trans) {
676
  struct stream * s = (struct stream *)NULL;
677
  int rdpprint_opcode = 0;
678
  int rdpprint_reply = 0;
679
  int size = 0;
680
  int error = 0;
681
  int fault = 0;
682
  int fhandle = 0;
683
  int uniqid = 0;
684
  int fdone = 0;
685
  BYTE buf[MAX_STREAM];
686
  uint32_t magic = 0;
687
  uint32_t crc32 = 0;
688
  uint32_t calc_crc32 = 0;
689
690
  DBGLOG("print","parent_data_in(): called");
691
692
  g_memset((BYTE *)buf,0,sizeof(BYTE)*MAX_STREAM);
693
694
  if (trans == 0)
695
  {
696
    return 0;
697
  }
698
  tc_mutex_lock(mutex_pcon);
699
  s = (struct stream *)trans_get_in_s(trans);
700
  in_uint32_le(s, magic);
701
  in_uint32_le(s, rdpprint_reply);
702
  in_uint32_le(s, size);
703
  in_uint32_le(s, fhandle);
704
  in_uint32_le(s, uniqid);
705
  in_uint32_le(s, crc32);
706
  if (size > 0) {
707
    error = trans_force_read(trans, size);
708
  }
709
  if (error == 0)
710
  {
711
    /* the entire message block has been read in, so process it: */
712
    fault = ((rdpprint_reply & RDPPRINT_ERROR) == 0) ? 0 : 1;
713
    rdpprint_opcode = rdpprint_reply & (~(RDPPRINT_REPLY | RDPPRINT_ERROR));
714
    MDBGLOG("print"," ** parent_data_in(): rdpprint_opcode = 0x%8.8x; rdpprint_reply = 0x%8.8x; fault = %d; uniqid = %d",rdpprint_opcode,rdpprint_reply,fault,uniqid);
715
    if (fault > 0) {
716
      NTSTATUS iostatus = { .Value = 0x00000000 };
717
      int reqid = -1;
718
      callback * cbdata = NULL;
719
      tbus lmut = (tbus)NULL;
720
      tbus lcv = (tbus)NULL;
721
      char * nterr = (char *)NULL;
722
723
      tc_mutex_lock(mutex_printop);
724
      in_uint32_le(s, iostatus.Value);
725
726
      nterr = ntstatus_string(iostatus.Value);
727
      MDBGLOG("print"," --> FAULT: \"%s\" (status = 0x%8.8x)",nterr,iostatus.Value);
728
      cbdata = &(g_reqids[uniqid]);
729
      reqid = cbdata->opid;
730
      if (reqid > -1) {
731
        get_mutex(reqid, &lmut);
732
	tc_mutex_lock(lmut);
733
        tc_mutex_unlock(mutex_printop);
734
	cbdata->IoStatus.Value = iostatus.Value;
735
        get_cv(reqid, &lcv);
736
	tc_cond_signal(lcv);
737
      }
738
      else {
739
	lmut = mutex_printop;
740
      }
741
      tc_mutex_unlock(lmut);
742
    }
743
    else switch(rdpprint_opcode) {
744
      case RDPPRINT_OPEN:
745
	DBGLOG("print"," ^^ (RDPPRINT_OPEN)");
746
	{
747
	  DR_DRIVE_CREATE_RSP iorsp;
748
	  int reqid = -1;
749
	  callback * cbdata = NULL;
750
	  tbus lmut = (tbus)NULL;
751
	  tbus lcv = (tbus)NULL;
752
	  tc_mutex_lock(mutex_printop);
753
	  cbdata = &(g_reqids[uniqid]);
754
	  reqid = cbdata->opid;
755
	  get_mutex(reqid, &lmut);
756
	  tc_mutex_lock(lmut);
757
	  tc_mutex_unlock(mutex_printop);
758
	  get_cv(reqid, &lcv);
759
	  construct_DR_DRIVE_CREATE_RSP(&iorsp);
760
	  if (size > 0 && size < MAX_STREAM) {
761
	    get_DR_DRIVE_CREATE_RSP(&iorsp, s);
762
	  }
763
	  cbdata->FileId = iorsp.DeviceCreateResponse.FileId;
764
	  MDBGLOG("print"," --> FileId = %d; fhandle = %d",cbdata->FileId,fhandle);
765
	  {
766
	    int tsize = 0;
767
	    char vdata[MAX_STREAM];
768
	    struct stream vs;
769
	    struct stream * v = &vs;
770
	    g_memset(&vdata,0,sizeof(char)*MAX_STREAM);
771
	    g_memset(v,0,sizeof(struct stream));
772
	    v->data = (char *)(&vdata);
773
	    v->p = v->data;
774
	    v->end = v->data;
775
	    v->size = MAX_STREAM;
776
	    send_DR_DRIVE_CREATE_RSP(&iorsp, v);
777
	    s_mark_end(v);
778
	    tsize = v->end - v->data;
779
	    g_hexdump_file("/tmp/taskq_print_open_reply.hexdump",v->data,tsize);
780
	  }
781
	  tc_cond_signal(lcv);
782
	  tc_mutex_unlock(lmut);
783
	}
784
	break;
785
      case RDPPRINT_READ:
786
	DBGLOG("print"," ^^ (RDPPRINT_READ)");
787
	{
788
	  DR_DRIVE_READ_RSP iorsp;
789
	  int reqid = -1;
790
	  callback * cbdata = (callback *)NULL;
791
	  tbus lmut = (tbus)NULL;
792
	  tbus lcv = (tbus)NULL;
793
	  tc_mutex_lock(mutex_printop);
794
	  cbdata = &(g_reqids[uniqid]);
795
	  reqid = cbdata->opid;
796
	  get_mutex(reqid, &lmut);
797
	  tc_mutex_lock(lmut);
798
	  tc_mutex_unlock(mutex_printop);
799
	  construct_DR_READ_RSP(&iorsp);
800
	  iorsp.ReadData = cbdata->userdata;
801
	  get_DR_READ_RSP(&iorsp, s);
802
	  cbdata->length = iorsp.Length;
803
	  get_cv(reqid,&lcv);
804
	  tc_cond_signal(lcv);
805
	  tc_mutex_unlock(lmut);
806
	  MDBGLOG("print"," ^^ (RDPPRINT_READ): iorsp.Length = %d; iorsp.ReadData = \"%s\"",iorsp.Length,iorsp.ReadData);
807
	}
808
	break;
809
      case RDPPRINT_WRITE:
810
	DBGLOG("print"," ^^ (RDPPRINT_WRITE)");
811
	{
812
	  DR_DRIVE_WRITE_RSP iorsp;
813
	  int reqid = -1;
814
	  callback * cbdata = (callback *)NULL;
815
	  tbus lmut = (tbus)NULL;
816
	  tbus lcv = (tbus)NULL;
817
	  tc_mutex_lock(mutex_printop);
818
	  cbdata = &(g_reqids[uniqid]);
819
	  reqid = cbdata->opid;
820
	  get_mutex(reqid, &lmut);
821
	  tc_mutex_lock(lmut);
822
	  tc_mutex_unlock(mutex_printop);
823
	  construct_DR_WRITE_RSP(&iorsp);
824
	  get_DR_WRITE_RSP(&iorsp, s);
825
	  cbdata->length = iorsp.Length;
826
	  get_cv(reqid,&lcv);
827
	  tc_cond_signal(lcv);
828
	  tc_mutex_unlock(lmut);
829
	}
830
	break;
831
      case RDPPRINT_IOCTL:
832
	DBGLOG("print"," ^^ (RDPPRINT_IOCTL)");
833
	{
834
	  DR_CONTROL_RSP iorsp;
835
	  int reqid = -1;
836
	  callback * cbdata = (callback *)NULL;
837
	  tbus lmut = (tbus)NULL;
838
	  tbus lcv = (tbus)NULL;
839
	  tc_mutex_lock(mutex_printop);
840
	  cbdata = &(g_reqids[uniqid]);
841
	  reqid = cbdata->opid;
842
	  get_mutex(reqid, &lmut);
843
	  tc_mutex_lock(lmut);
844
	  tc_mutex_unlock(mutex_printop);
845
	  construct_DR_CONTROL_RSP(&iorsp);
846
	  iorsp.OutputBuffer = cbdata->userdata;
847
	  get_DR_CONTROL_RSP(&iorsp, s);
848
	  cbdata->length = iorsp.OutputBufferLength;
849
	  get_cv(reqid,&lcv);
850
	  tc_cond_signal(lcv);
851
	  tc_mutex_unlock(lmut);
852
	  MDBGLOG("print"," ^^ (RDPPRINT_IOCTL): iorsp.OutputBufferLength = %d;",iorsp.OutputBufferLength);
853
	}
854
	break;
855
      case RDPPRINT_CLOSE:
856
	DBGLOG("print"," ^^ (RDPPRINT_CLOSE)");
857
	{
858
	  int reqid = -1;
859
	  callback * cbdata = (callback *)NULL;
860
	  tbus lmut = (tbus)NULL;
861
	  tbus lcv = (tbus)NULL;
862
	  tc_mutex_lock(mutex_printop);
863
	  cbdata = &(g_reqids[uniqid]);
864
	  reqid = cbdata->opid;
865
	  get_mutex(reqid, &lmut);
866
	  tc_mutex_lock(lmut);
867
	  tc_mutex_unlock(mutex_printop);
868
	  get_cv(reqid,&lcv);
869
	  tc_cond_signal(lcv);
870
	  tc_mutex_unlock(lmut);
871
	}
872
	break;
873
      case RDPPRINT_INIT:
874
	DBGLOG("print"," ^^ (rdpprint_INIT)");
875
	{
876
	  int reqid = -1;
877
	  callback * cbdata = (callback *)NULL;
878
	  filelist * lst = (filelist *)NULL;
879
	  tbus lmut = (tbus)NULL;
880
	  tbus lcv = (tbus)NULL;
881
	}
882
	break;
883
      case RDPPRINT_DESTROY:
884
	DBGLOG("print"," ^^ (rdpprint_DESTROY)");
885
	exit(0);
886
	break;
887
      case RDPPRINT_ERROR:
888
	DBGLOG("print"," ^^ (RDPPRINT_ERROR)");
889
	exit(0);
890
	break;
891
    }
892
  }
893
  tc_mutex_unlock(mutex_pcon);
894
  return error;
895
}
896
897
typedef struct _handle_printer_loop_args {
898
	rdpprint *		printer;
899
	struct trans *		pcon;
900
	tbus			objs[2];
901
	int			num_objs;
902
	int			timeout;
903
	int			check_parent;
904
	int			check_device;
905
} handle_printer_loop_args;
906
907
static void * APP_CC
908
loop_parent_print(void * inargs) {
909
  handle_printer_loop_args * largs = (handle_printer_loop_args *)inargs;
910
  rdpprint * printer = largs->printer;
911
  struct trans * pcon = largs->pcon;
912
  tbus * objs = (tbus *)(largs->objs);
913
  int num_objs = largs->num_objs;
914
  int timeout = largs->timeout;
915
  int check_parent = largs->check_parent;
916
  int check_device = largs->check_device;
917
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_parent > 0) {
918
    /* handle any inbound communication from the parent process: */
919
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
920
      if ((check_parent > 0) && g_is_wait_obj_set(objs[0])) {
921
	tc_mutex_lock(mutex_parent);
922
	if (trans_check_wait_objs(pcon) != 0) {
923
	  DBGLOG("print","ERROR [loop_parent_print()]: ");
924
	  //rv = -1;
925
	  break;
926
	}
927
	tc_mutex_unlock(mutex_parent);
928
      }
929
    }
930
  }
931
  tc_thread_exit(NULL);
932
}
933
934
static void * APP_CC
935
loop_device_print(void * inargs) {
936
  handle_printer_loop_args * largs = (handle_printer_loop_args *)inargs;
937
  rdpprint * printer = largs->printer;
938
  struct trans * pcon = largs->pcon;
939
  tbus * objs = (tbus *)(largs->objs);
940
  int num_objs = largs->num_objs;
941
  int timeout = largs->timeout;
942
  int check_parent = largs->check_parent;
943
  int check_device = largs->check_device;
944
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_device > 0) {
945
    /* handle communication from pseudo-device (i.e., the artificial serial or parallel printer on the server): */
946
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
947
      if ((check_device > 0) && ((num_objs == 2 && g_is_wait_obj_set(objs[1])) || (num_objs == 1 && g_is_wait_obj_set(objs[0])))) {
948
	tc_mutex_lock(mutex_device);
949
	rdpprint_cycle(printer);
950
	tc_mutex_unlock(mutex_device);
951
      }
952
    }
953
  }
954
  tc_thread_exit(NULL);
955
}
956
957
/*****************************************************************************/
958
static int APP_CC
959
rdpprint_cycle(rdpprint * printer) {
960
  int rv = 0;
961
  return rv;
962
}
963
964
/*****************************************************************************/
965
int APP_CC
966
handle_printer(tbus sck, rdpprint * printer) {
967
  int rv = 0;
968
  int brk = 0;
969
  struct trans * pcon = (struct trans *)NULL;
970
  tbus objs[2] = { -1, -1 };
971
  int num_objs = 0;
972
  int timeout = 0;
973
  int check_parent = 0;
974
  int check_device = 0;
975
  handle_printer_loop_args largs;
976
  tbus thread_parent;
977
  tbus thread_device;
978
979
  MDBGLOG("print","handle_printer(): sck = %d",sck);
980
  g_memset(&largs,0,sizeof(handle_printer_loop_args));
981
  g_memset(&thread_parent,0,sizeof(tbus));
982
  g_memset(&thread_device,0,sizeof(tbus));
983
984
  mut = (tc_p)&g_mutex;
985
  mutex_pcon = (tc_p)&g_mutex_pcon;
986
  mutex_print = (tc_p)&g_mutex_print;
987
  mutex_printop = (tc_p)&g_mutex_printop;
988
  mutex_parent = (tc_p)&g_mutex_parent;
989
  mutex_device = (tc_p)&g_mutex_device;
990
  mutex_reqid = (tc_p)&g_mutex_reqid;
991
  tc_mutex_init(mut,NULL);
992
  tc_mutex_init(mutex_pcon,NULL);
993
  tc_mutex_init(mutex_print,NULL);
994
  tc_mutex_init(mutex_printop,NULL);
995
  tc_mutex_init(mutex_parent,NULL);
996
  tc_mutex_init((tc_t *)mutex_device,NULL);
997
  tc_mutex_init((tc_t *)mutex_reqid,NULL);
998
999
  tc_mutex_lock(mutex_pcon);
1000
  tc_mutex_lock(mutex_print);
1001
1002
  init_reqids();
1003
1004
    /* set up pcon as a transmission channel to the parent */
1005
  pcon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
1006
  pcon->trans_data_in = &parent_data_in;
1007
  pcon->header_size = 24;
1008
  rv = trans_attach(pcon, sck);
1009
  pcon->sck = sck;
1010
  printer->ccon = pcon;
1011
1012
  tc_mutex_unlock(mutex_pcon);
1013
  tc_mutex_unlock(mutex_print);
1014
1015
  if (rv > -1) {
1016
1017
    tc_mutex_lock(mutex_pcon);
1018
    tc_mutex_lock(mutex_print);
1019
1020
    /* add pcon to the set of monitored channels */
1021
    if (pcon != NULL && pcon->sck > 0) {
1022
      objs[num_objs] = pcon->sck;
1023
      num_objs++;
1024
      check_parent = 1;
1025
    }
1026
1027
    /* add the appropriate ttyS* file descriptor to the set of monitored channels */
1028
    if (printer->fd > 0) {
1029
      objs[num_objs] = printer->fd;
1030
      num_objs++;
1031
      check_device = 1;
1032
    }
1033
1034
    tc_mutex_unlock(mutex_pcon);
1035
    tc_mutex_unlock(mutex_print);
1036
1037
    /* monitor the above channels for input and respond appropriately */
1038
    if (num_objs > 0 && objs[0] > -1) {
1039
1040
      tc_mutex_lock(mutex_pcon);
1041
      tc_mutex_lock(mutex_print);
1042
1043
      largs.printer = printer;
1044
      largs.pcon = pcon;
1045
      largs.objs[0] = objs[0];
1046
      largs.objs[1] = objs[1];
1047
      largs.num_objs = num_objs;
1048
      largs.timeout = timeout;
1049
      largs.check_parent = check_parent;
1050
      largs.check_device = check_device;
1051
1052
      tc_mutex_unlock(mutex_pcon);
1053
      tc_mutex_unlock(mutex_print);
1054
1055
1056
      if (objs != NULL && num_objs > 0 && (check_parent > 0 || check_device > 0)) {
1057
	tc_thread_init(&thread_parent,&loop_parent_print,&largs);
1058
	tc_thread_init(&thread_device,&loop_device_print,&largs);
1059
	tc_thread_join(thread_parent,NULL);
1060
	tc_thread_join(thread_device,NULL);
1061
      }
1062
    }
1063
  }
1064
1065
  return rv;
1066
}
1067
1068
static int APP_CC get_reqid(int * inarg) {
1069
  int rv = 0;
1070
  if (inarg == NULL) {
1071
    rv = -1;
1072
  }
1073
  else {
1074
    *inarg = -1;
1075
    tc_mutex_lock(mutex_reqid);
1076
    for (rv = 1; rv < MAX_REQID; rv++) {
1077
      if (g_reqids[rv].opid == -1) {
1078
	*inarg = rv;
1079
	g_reqids[rv].opid = rv;
1080
	tc_mutex_init(&(g_reqids[rv].mutex),NULL);
1081
	tc_cond_create(&(g_reqids[rv].cv),NULL);
1082
	break;
1083
      }
1084
    }
1085
    tc_mutex_unlock(mutex_reqid);
1086
  }
1087
  return rv;
1088
}
1089
1090
static int APP_CC free_reqid(int inarg) {
1091
  int rv = 0;
1092
  if (inarg < 0 || inarg > MAX_REQID) {
1093
    rv = -1;
1094
  }
1095
  else if (g_reqids[inarg].opid > -1 && g_reqids[inarg].opid <= MAX_REQID) {
1096
    tc_mutex_lock(mutex_reqid);
1097
    tc_mutex_deinit(&(g_reqids[inarg].mutex));
1098
    tc_cond_deinit(&(g_reqids[inarg].cv));
1099
    g_memset(&(g_reqids[inarg]),0,sizeof(callback));
1100
    g_reqids[inarg].opid = -1;
1101
    tc_mutex_unlock(mutex_reqid);
1102
  }
1103
  return rv;
1104
}
1105
1106
static int APP_CC init_reqids() {
1107
  int rv = 0;
1108
  tc_mutex_lock(mutex_reqid);
1109
  g_memset((callback *)g_reqids,0,sizeof(callback)*MAX_REQID);
1110
  for (rv = 0; rv < MAX_REQID; rv++) {
1111
    g_reqids[rv].opid = -1;
1112
  }
1113
  tc_mutex_unlock(mutex_reqid);
1114
  rv = 0;
1115
  return rv;
1116
}
1117
1118
static int APP_CC get_mutex(int reqid, tc_t * inarg) {
1119
  int rv = 0;
1120
  
1121
  if (reqid >= 0 && reqid < MAX_REQID) {
1122
    tc_mutex_lock(mutex_reqid);
1123
    *inarg = (tc_t)g_reqids[reqid].mutex;
1124
    tc_mutex_unlock(mutex_reqid);
1125
  }
1126
  else {
1127
    rv = -1;
1128
  }
1129
  return rv;
1130
}
1131
1132
static int APP_CC get_cv(int reqid, tc_t * inarg) {
1133
  int rv = 0;
1134
  if (reqid >= 0 && reqid < MAX_REQID) {
1135
    tc_mutex_lock(mutex_reqid);
1136
    *inarg = (tc_t)(g_reqids[reqid].cv);
1137
    tc_mutex_unlock(mutex_reqid);
1138
  }
1139
  else {
1140
    rv = -1;
1141
  }
1142
  return rv;
1143
}
1144
1145
static char * APP_CC rdpprint_get_dircomponent(char * rv, const char * name) {
1146
  char * npos = (char *)NULL;
1147
1148
  if (name != NULL) {
1149
    npos = (char *)g_strrchr(name, (int)'/');
1150
    if (npos > 0) {
1151
      if (rv == NULL) {
1152
	rv = (char *)g_malloc(sizeof(char) * ((npos - name) + 1), 1);
1153
      }
1154
      g_strncpy(rv, name, (npos - name));
1155
    }
1156
  }
1157
1158
  return rv;
1159
}
1160
1161
/********************************************************/
1162
/*	refactor a filename into canonical form		*/
1163
/********************************************************/
1164
static void APP_CC rdpprint_clean_fname(char * name) {
1165
        char * p = (char *)NULL;
1166
	char * p2 = (char *)NULL;
1167
        int l = 0;
1168
        int modified = 1;
1169
	const char forbidden[] = {'/', '[', ']', ':', '|', '<', '>', '+', '=', ';', ',', '?', 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
1170
1171
        if (name == NULL) {
1172
	  return;
1173
	}
1174
1175
        MDBGLOG("print","rdpprint_clean_fname() [%s]:\n", name);
1176
1177
	while (modified) {
1178
		modified = 0;
1179
		if ((p=strstr(name,"/./"))) {
1180
			modified = 1;
1181
			while (*p) {
1182
				p[0] = p[2];
1183
				p++;
1184
			}
1185
			MDBGLOG("print", "\tclean 1 (/./) produced [%s]\n", name);
1186
		}
1187
		if ((p=strstr(name,"//"))) {
1188
			modified = 1;
1189
			while (*p) {
1190
				p[0] = p[1];
1191
				p++;
1192
			}
1193
			MDBGLOG("print", "\tclean 2 (//) produced [%s]\n", name);
1194
		}
1195
		if (strcmp(name,"/../")==0) {
1196
			modified = 1;
1197
			name[1] = 0;
1198
			MDBGLOG("print", "\tclean 3 (^/../$) produced [%s]\n", name);
1199
		}
1200
		if ((p=strstr(name,"/../"))) {
1201
			modified = 1;
1202
			for (p2 = (p > name ? p-1 : p); p2 > name; p2--) {
1203
				if (p2[0] == '/') {
1204
					break;
1205
				}
1206
			}
1207
			if (p2 > name) p2++;
1208
			while (*p2) {
1209
				p2[0] = p[3];
1210
				p2++;
1211
				p++;
1212
			}
1213
			MDBGLOG("print", "\tclean 4 (/../) produced [%s]\n", name);
1214
		}
1215
1216
                if (strcmp(name,"/..")==0) {
1217
                        modified = 1;
1218
                        name[1] = 0;
1219
                        MDBGLOG("print", "\tclean 5 (^/..$) produced [%s]\n", name);
1220
                }
1221
1222
                l = strlen(name);
1223
                p = l>=3?(name+l-3):name;
1224
                if (strcmp(p,"/..")==0) {
1225
                        modified = 1;
1226
                        for (p2=p-1;p2>name;p2--) {
1227
                                if (p2[0] == '/') break;
1228
                        }
1229
                        if (p2==name) {
1230
                                p[0] = '/';
1231
                                p[1] = 0;
1232
                        } else {
1233
                                p2[0] = 0;
1234
                        }
1235
                        MDBGLOG("print", "\tclean 6 (/..) produced [%s]\n", name);
1236
                }
1237
1238
                l = strlen(name);
1239
                p = l>=2?(name+l-2):name;
1240
                if (strcmp(p,"/.")==0) {
1241
                        modified = 1;
1242
                        if (p == name) {
1243
                                p[1] = 0;
1244
                        } else {
1245
                                p[0] = 0;
1246
                        }
1247
                        MDBGLOG("print", "\tclean 7 (/.) produced [%s]\n", name);
1248
                }
1249
1250
                if (strncmp(p=name,"./",2) == 0) {
1251
                        modified = 1;
1252
                        do {
1253
                                p[0] = p[2];
1254
                        } while (*p++);
1255
                        MDBGLOG("print", "\tclean 8 (^./) produced [%s]\n", name);
1256
                }
1257
1258
                l = strlen(p=name);
1259
                if (l > 1 && p[l-1] == '/') {
1260
                        modified = 1;
1261
                        p[l-1] = 0;
1262
                        MDBGLOG("print", "\tclean 9 (/) produced [%s]\n", name);
1263
                }
1264
        }
1265
1266
        MDBGLOG("print","rdpprint_clean_fname() done [%s].\n", name);
1267
}
1268
1269
static int APP_CC ntstatus_to_errcode(DWORD ntstat) {
1270
  int retstat = 0;
1271
1272
  switch (ntstat) {
1273
	case 0:
1274
	  retstat = 0;
1275
	  break;
1276
	case STATUS_ACCESS_DENIED:
1277
	case STATUS_ACCESS_VIOLATION:
1278
	case STATUS_NETWORK_ACCESS_DENIED:
1279
	case STATUS_UNSUCCESSFUL:
1280
	  retstat = -EACCES;
1281
	  break;
1282
	case STATUS_GUARD_PAGE_VIOLATION:
1283
	case STATUS_INVALID_PARAMETER:
1284
	case STATUS_BAD_DEVICE_TYPE:
1285
	case STATUS_BAD_NETWORK_NAME:
1286
	case STATUS_INVALID_VOLUME_LABEL:
1287
	case STATUS_BAD_TOKEN_TYPE:
1288
	case STATUS_INVALID_GROUP_ATTRIBUTES:
1289
	case STATUS_BAD_MASTER_BOOT_RECORD:
1290
	case STATUS_INVALID_OPLOCK_PROTOCOL:
1291
	case STATUS_INVALID_INFO_CLASS:
1292
	case STATUS_INVALID_DEVICE_REQUEST:
1293
	case STATUS_INVALID_SYSTEM_SERVICE:
1294
	case STATUS_ILLEGAL_INSTRUCTION:
1295
	case STATUS_INVALID_LOCK_SEQUENCE:
1296
	case STATUS_INVALID_VIEW_SIZE:
1297
	case STATUS_INVALID_FILE_FOR_SECTION:
1298
	case STATUS_INVALID_DISPOSITION:
1299
	case STATUS_INVALID_UNWIND_TARGET:
1300
	case STATUS_INVALID_PORT_ATTRIBUTES:
1301
	case STATUS_INVALID_PARAMETER_MIX:
1302
	case STATUS_OBJECT_NAME_INVALID:
1303
	case STATUS_INVALID_VARIANT:
1304
	case STATUS_POWER_STATE_INVALID:
1305
	case STATUS_INVALID_DEVICE_OBJECT_PARAMETER:
1306
	case STATUS_INVALID_BLOCK_LENGTH:
1307
	  retstat = -EINVAL;
1308
	  break;
1309
#ifdef ENOMEDIUM
1310
	case STATUS_NO_MEDIA_IN_DEVICE:
1311
	case STATUS_UNRECOGNIZED_MEDIA:
1312
	  retstat = -ENOMEDIUM;
1313
	  break;
1314
#endif
1315
	case STATUS_SHARING_VIOLATION:
1316
	case STATUS_FILE_LOCK_CONFLICT:
1317
	case STATUS_LOCK_NOT_GRANTED:
1318
	case STATUS_SHARING_PAUSED:
1319
	case STATUS_SHARED_POLICY:
1320
	case STATUS_NOT_LOCKED:
1321
	case STATUS_PIPE_BUSY:
1322
	case STATUS_CONNECTION_IN_USE:
1323
	case STATUS_WAIT_FOR_OPLOCK:
1324
	  retstat = -EBUSY;
1325
	  break;
1326
	case STATUS_LOGON_FAILURE:
1327
	case STATUS_ACCOUNT_RESTRICTION:
1328
	case STATUS_ILL_FORMED_PASSWORD:
1329
	case STATUS_PASSWORD_RESTRICTION:
1330
	case STATUS_INVALID_LOGON_HOURS:
1331
	case STATUS_INVALID_WORKSTATION:
1332
	case STATUS_PASSWORD_EXPIRED:
1333
	case STATUS_ACCOUNT_DISABLED:
1334
	case STATUS_WRONG_PASSWORD:
1335
	case STATUS_SECTION_PROTECTION:
1336
	case STATUS_PRIVILEGE_NOT_HELD:
1337
	case STATUS_PRIVILEGED_INSTRUCTION:
1338
	case STATUS_PASSWORD_MUST_CHANGE:
1339
	case STATUS_ACCOUNT_LOCKED_OUT:
1340
	case STATUS_RESOURCE_NOT_OWNED:
1341
	case STATUS_LICENSE_VIOLATION:
1342
	case STATUS_LICENSE_QUOTA_EXCEEDED:
1343
	case STATUS_EVALUATION_EXPIRATION:
1344
	case STATUS_COPY_PROTECTION_FAILURE:
1345
	case STATUS_SMARTCARD_WRONG_PIN:
1346
	case STATUS_SMARTCARD_CARD_BLOCKED:
1347
	case STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED:
1348
	case STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT:
1349
	case STATUS_ACCESS_DISABLED_BY_POLICY_PATH:
1350
	case STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER:
1351
	case STATUS_ACCESS_DISABLED_BY_POLICY_OTHER:
1352
	case STATUS_CSS_AUTHENTICATION_FAILURE:
1353
	case STATUS_CSS_KEY_NOT_PRESENT:
1354
	case STATUS_CSS_KEY_NOT_ESTABLISHED:
1355
	case STATUS_INSUFFICIENT_LOGON_INFO:
1356
	  retstat = -EPERM;
1357
	  break;
1358
	case STATUS_DEVICE_DOES_NOT_EXIST:
1359
	case STATUS_DEVICE_NOT_CONNECTED:
1360
	case STATUS_DEVICE_POWER_FAILURE:
1361
	case STATUS_DEVICE_REMOVED:
1362
	case STATUS_PLUGPLAY_NO_DEVICE:
1363
	case STATUS_VOLUME_DISMOUNTED:
1364
	case STATUS_NOINTERFACE:
1365
	case STATUS_PARTITION_FAILURE:
1366
	  retstat = -ENODEV;
1367
	  break;
1368
	case STATUS_NO_MORE_FILES:
1369
	case STATUS_OBJECT_NAME_NOT_FOUND:
1370
	case STATUS_NOT_FOUND:
1371
	case STATUS_INVALID_PLUGPLAY_DEVICE_PATH:
1372
	case STATUS_NO_SUCH_FILE:
1373
	case STATUS_NETWORK_NAME_DELETED:
1374
	case STATUS_FILE_IS_OFFLINE:
1375
	case STATUS_MOUNT_POINT_NOT_RESOLVED:
1376
	  retstat = -ENOENT;
1377
	  break;
1378
	case STATUS_LOGON_SESSION_EXISTS:
1379
	case STATUS_DUPLICATE_NAME:
1380
	case STATUS_ALIAS_EXISTS:
1381
	case STATUS_ADDRESS_ALREADY_EXISTS:
1382
	case STATUS_DUPLICATE_OBJECTID:
1383
	case STATUS_OBJECTID_EXISTS:
1384
	  retstat = -EEXIST;
1385
	  break;
1386
	case STATUS_WRONG_VOLUME:
1387
	  retstat = -EXDEV;
1388
	  break;
1389
	case STATUS_BUFFER_TOO_SMALL:
1390
	case STATUS_SECTION_TOO_BIG:
1391
	case STATUS_SYSTEM_HIVE_TOO_LARGE:
1392
	  retstat = -E2BIG;
1393
	  break;
1394
	case STATUS_MEMORY_NOT_ALLOCATED:
1395
	case STATUS_NO_MEMORY:
1396
	case STATUS_INSUFFICIENT_RESOURCES:
1397
	case STATUS_INSUFF_SERVER_RESOURCES:
1398
	  retstat = -ENOMEM;
1399
	  break;
1400
	case STATUS_INVALID_HANDLE:
1401
	case STATUS_FILE_INVALID:
1402
	case STATUS_INVALID_PORT_HANDLE:
1403
	case STATUS_FILE_DELETED:
1404
	case STATUS_FILE_CLOSED:
1405
	case STATUS_FILE_CORRUPT_ERROR:
1406
	case STATUS_USER_MAPPED_FILE:
1407
	case STATUS_NOT_A_REPARSE_POINT:
1408
	case STATUS_DIRECTORY_IS_A_REPARSE_POINT:
1409
	case STATUS_FILE_NOT_ENCRYPTED:
1410
	case STATUS_FILE_ENCRYPTED:
1411
	case STATUS_CORRUPT_SYSTEM_FILE:
1412
	case STATUS_HANDLE_NOT_CLOSABLE:
1413
	  retstat = -EBADF;
1414
	  break;
1415
	case STATUS_FILES_OPEN:
1416
	  retstat = -EMFILE;
1417
	  break;
1418
	case STATUS_TOO_MANY_OPENED_FILES:
1419
	  retstat = -ENFILE;
1420
	  break;
1421
	case STATUS_PIPE_NOT_AVAILABLE:
1422
	case STATUS_INVALID_PIPE_STATE:
1423
	case STATUS_PIPE_BROKEN:
1424
	case STATUS_PIPE_EMPTY:
1425
	  retstat = -EPIPE;
1426
	  break;
1427
	case STATUS_DISK_FULL:
1428
	case STATUS_NO_LOG_SPACE:
1429
	case STATUS_LOG_FILE_FULL:
1430
	case STATUS_NO_SPOOL_SPACE:
1431
	case STATUS_PRINT_QUEUE_FULL:
1432
	case STATUS_DESTINATION_ELEMENT_FULL:
1433
	  retstat = -ENOSPC;
1434
	  break;
1435
	case STATUS_MEDIA_WRITE_PROTECTED:
1436
	  retstat = -EROFS;
1437
	  break;
1438
	case STATUS_DIRECTORY_NOT_EMPTY:
1439
	  retstat = -ENOTEMPTY;
1440
	  break;
1441
	case STATUS_RETRY:
1442
	  retstat = -EAGAIN;
1443
	  break;
1444
	case STATUS_OBJECT_PATH_NOT_FOUND:
1445
	case STATUS_NOT_A_DIRECTORY:
1446
	  retstat = -ENOTDIR;
1447
	  break;
1448
	case STATUS_FILE_IS_A_DIRECTORY:
1449
	  retstat = -EISDIR;
1450
	  break;
1451
	case STATUS_UNEXPECTED_IO_ERROR:
1452
	case STATUS_IO_PRIVILEGE_FAILED:
1453
	case STATUS_DEVICE_NOT_READY:
1454
	case STATUS_IO_DEVICE_ERROR:
1455
	case STATUS_OPEN_FAILED:
1456
	case STATUS_REPLY_MESSAGE_MISMATCH:
1457
	case STATUS_LOST_WRITEBEHIND_DATA:
1458
	  retstat = -EIO;
1459
	  break;
1460
	case STATUS_NOT_SUPPORTED:
1461
	case STATUS_ILLEGAL_FUNCTION:
1462
	case STATUS_WMI_NOT_SUPPORTED:
1463
	  retstat = -EOPNOTSUPP;
1464
	  break;
1465
	case STATUS_PIPE_DISCONNECTED:
1466
	case STATUS_CONNECTION_ABORTED:
1467
	case STATUS_CONNECTION_DISCONNECTED:
1468
	case STATUS_CONNECTION_RESET:
1469
	  retstat = -ECONNRESET;
1470
	  break;
1471
	default:
1472
	  break;
1473
  }
1474
1475
  return retstat;
1476
}
1477
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/rdpsc.c (+1478 lines)
Line 0    Link Here 
1
/*
2
 *
3
 * Smartcard redirection over RDP
4
 *
5
 */
6
7
#include "params.h"
8
9
#include <pthread.h>
10
#include <ctype.h>
11
#include <errno.h>
12
#include <fcntl.h>
13
#include <stdlib.h>
14
#include <stdio.h>
15
#include <string.h>
16
#include <termios.h>
17
#include <unistd.h>
18
#include <sys/types.h>
19
#include <sys/sysmacros.h>
20
21
#include "log.h"
22
#include "arch.h"
23
#include "parse.h"
24
#include "defines.h"
25
#include "rdpdr.h"
26
#include "rdpdr_methods.h"
27
#include "trans.h"
28
#include "devredir_defs.h"
29
#include "global.h"
30
#include "thread_calls.h"
31
#include "dbg.h"
32
33
static int g_fd = -1;
34
static rdpsc * g_smartcard = (rdpsc *)NULL;
35
36
static const uint32_t pmagic = RDP_PACKET_MAGIC;
37
38
#ifndef MAX_REQID
39
#define MAX_REQID	25
40
#endif
41
static callback g_reqids[MAX_REQID];
42
43
#ifndef MAX_MUTEX
44
#define MAX_MUTEX	25
45
#endif
46
//static pthread_mutex_t g_mutexes[MAX_MUTEX];
47
//static pthread_cond_t g_condition_variables[MAX_MUTEX];
48
49
//pthread_mutex_t mutex_device;
50
extern tc_t g_mutex;
51
extern tc_p mut;
52
53
static tc_t g_mutex_pcon;
54
static tc_t g_mutex_smartcard;
55
static tc_t g_mutex_device;
56
static tc_t g_mutex_parent;
57
static tc_t g_mutex_smartcardop;
58
static tc_t g_mutex_reqid;
59
static tc_t g_mutex_device;
60
static tc_p mutex_pcon = (tc_p)NULL;
61
static tc_p mutex_smartcard = (tc_p)NULL;
62
static tc_p mutex_parent = (tc_p)NULL;
63
static tc_p mutex_smartcardop = (tc_p)NULL;
64
static tc_p mutex_reqid = (tc_p)NULL;
65
static tc_p mutex_device = (tc_p)NULL;
66
67
static int APP_CC rdpsc_open(tbus);
68
static int APP_CC rdpsc_open_args(tbus, uint32_t, uint32_t, uint32_t, uint32_t);
69
static int APP_CC rdpsc_release(tbus);
70
static int APP_CC rdpsc_ioctl(tbus, int, size_t, void *, size_t, void *);
71
72
static int APP_CC rdpsc_cycle(rdpsc *);
73
74
static int APP_CC get_reqid(int *);
75
static int APP_CC free_reqid(int);
76
static int APP_CC init_reqids(void);
77
static int APP_CC get_mutex(int, tbus *);
78
static int APP_CC get_cv(int, tbus *);
79
static int APP_CC ntstatus_to_errcode(DWORD);
80
81
extern int APP_CC get_RDPDR_HEADER(RDPDR_HEADER *, struct stream *);
82
extern int APP_CC get_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *, struct stream *);
83
extern int APP_CC get_DR_CREATE_RSP(DR_CREATE_RSP *, struct stream *);
84
extern int APP_CC get_DR_DRIVE_QUERY_INFORMATION_RSP(DR_DRIVE_QUERY_INFORMATION_RSP *, struct stream *);
85
extern int APP_CC get_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *, struct stream *);
86
extern int APP_CC construct_RDPDR_HEADER(RDPDR_HEADER *);
87
extern int APP_CC construct_DR_DEVICE_IOCOMPLETION(DR_DEVICE_IOCOMPLETION *);
88
extern int APP_CC construct_DR_CREATE_RSP(DR_CREATE_RSP *);
89
extern int APP_CC construct_DR_DRIVE_CREATE_RSP(DR_DRIVE_CREATE_RSP *);
90
extern char * APP_CC ntstatus_string(uint32_t);
91
92
static int APP_CC parent_data_in(struct trans *);
93
94
/*
95
 *	Port open operation
96
 */
97
int rdpsc_open(tbus fh) {
98
    int retstat = 0;
99
    struct stream * s = NULL;
100
    int idx = 0;
101
    struct trans * pcon = (struct trans *)NULL;
102
    int rdpsc_opcode = 0x00000000;
103
    int size = 0x00000000;
104
    rdpsc_data rdata;
105
    tc_p lmutex = (tbus)NULL;
106
    tc_p lcv = (tbus)NULL;
107
    callback * cbdata = NULL;
108
    uint32_t pflags = 0x00000000;
109
    uint32_t pshare = 0x00000000;
110
    uint32_t poptions = 0x00000000;
111
    uint32_t pattributes = 0x00000000;
112
    uint32_t magic = 0;
113
    uint32_t crc32 = 0;
114
    uint32_t calc_crc32 = 0;
115
    int reqid = -1;
116
    int uniqid = 0;
117
118
    MDBGLOG("smartcard","\n\nrdpsc_open (fh=\"%d\")\n",fh);
119
120
    g_memset(&rdata,0,sizeof(rdpsc_data));
121
122
    tc_mutex_lock(mutex_smartcardop);
123
    get_reqid(&reqid);
124
    get_mutex(reqid, &lmutex);
125
    tc_mutex_lock(lmutex);
126
    tc_mutex_unlock(mutex_smartcardop);
127
128
    get_cv(reqid, &lcv);
129
    cbdata = &(g_reqids[reqid]);
130
131
    pflags = GENERIC_ALL;
132
    pshare |= (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
133
134
    rdpsc_opcode = RDPSC_OPEN;
135
    uniqid = reqid;
136
137
    tc_mutex_lock(mutex_pcon);
138
    pcon = g_smartcard->ccon;
139
    pcon->callback_data = cbdata;
140
    s = trans_get_out_s(pcon, MAX_STREAM);
141
    out_uint32_le(s, pmagic);
142
    out_uint32_le(s, rdpsc_opcode);
143
    out_uint32_le(s, size + 16);
144
    out_uint32_le(s, fh);
145
    out_uint32_le(s, uniqid);
146
    out_uint32_le(s, crc32);
147
    out_uint32_le(s, pflags);
148
    out_uint32_le(s, pshare);
149
    out_uint32_le(s, poptions);
150
    out_uint32_le(s, pattributes);
151
    s_mark_end(s);
152
    size = s->end - s->data;
153
154
    g_hexdump_file("/tmp/taskq_smartcard_open.hexdump", s->data, size);
155
    MDBGLOG("smartcard"," ** rdpsc_open(): sending [g_fd = %d]", g_fd);
156
    trans_force_write(pcon);
157
    g_memset(s->data,0,MAX_STREAM);
158
    DBGLOG("smartcard","sent.");
159
    tc_mutex_unlock(mutex_pcon);
160
161
    DBGLOG("smartcard","entering g_obj_wait loop:");
162
    tc_cond_wait(lcv, lmutex);
163
    DBGLOG("smartcard","exiting g_obj_wait loop.");
164
165
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
166
    if (retstat < 0) {
167
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
168
      MDBGLOG("smartcard","ERROR [rdpsc_open()]: \"%s\" (retstat = %d; cbdata->IoStatus.Fields.Sev = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
169
    }
170
171
    MDBGLOG("smartcard","rdpsc_open(): done. (fh = %d; retstat = %d)",fh,retstat);
172
173
    tc_mutex_unlock(lmutex);
174
    free_reqid(reqid);
175
176
    return retstat;
177
}
178
179
int rdpsc_open_args(tbus fh, uint32_t pflags, uint32_t pshare, uint32_t poptions, uint32_t pattributes) {
180
    int retstat = 0;
181
    struct stream * s = NULL;
182
    int idx = 0;
183
    struct trans * pcon = (struct trans *)NULL;
184
    int rdpsc_opcode = 0x00000000;
185
    int size = 0x00000000;
186
    rdpsc_data rdata;
187
    tc_p lmutex = (tbus)NULL;
188
    tc_p lcv = (tbus)NULL;
189
    callback * cbdata = NULL;
190
    int reqid = -1;
191
    int fhandle = 0;
192
    int uniqid = 0;
193
    uint32_t magic = 0;
194
    uint32_t crc32 = 0;
195
    uint32_t calc_crc32 = 0;
196
197
    MDBGLOG("smartcard","\n\nrdpsc_open_args (fh = \"%d\"; pflags = 0x%8.8x; pshare  = 0x%8.8x; poptions = 0x%8.8x)\n",fh,pflags,pshare,poptions);
198
199
    g_memset(&rdata,0,sizeof(rdpsc_data));
200
201
    tc_mutex_lock(mutex_smartcardop);
202
    get_reqid(&reqid);
203
    get_mutex(reqid, &lmutex);
204
    tc_mutex_lock(lmutex);
205
    tc_mutex_unlock(mutex_smartcardop);
206
207
    get_cv(reqid, &lcv);
208
    cbdata = &(g_reqids[reqid]);
209
210
    rdpsc_opcode = RDPSC_OPEN;
211
    uniqid = reqid;
212
213
    tc_mutex_lock(mutex_pcon);
214
    pcon = g_smartcard->ccon;
215
    pcon->callback_data = cbdata;
216
    s = trans_get_out_s(pcon, MAX_STREAM);
217
    out_uint32_le(s, pmagic);
218
    out_uint32_le(s, rdpsc_opcode);
219
    out_uint32_le(s, size + 16);
220
    out_uint32_le(s, fhandle);
221
    out_uint32_le(s, uniqid);
222
    out_uint32_le(s, crc32);
223
    out_uint32_le(s, pflags);
224
    out_uint32_le(s, pshare);
225
    out_uint32_le(s, poptions);
226
    out_uint32_le(s, pattributes);
227
    s_mark_end(s);
228
    size = s->end - s->data;
229
230
    g_hexdump_file("/tmp/taskq_smartcard_open_args.hexdump", s->data, size);
231
    MDBGLOG("smartcard"," ** rdpsc_open_args(): sending [g_fd = %d]", g_fd);
232
    trans_force_write(pcon);
233
    g_memset(s->data,0,MAX_STREAM);
234
    DBGLOG("smartcard","sent.");
235
    tc_mutex_unlock(mutex_pcon);
236
237
    DBGLOG("smartcard","entering g_obj_wait loop:");
238
    tc_cond_wait(lcv, lmutex);
239
    DBGLOG("smartcard","exiting g_obj_wait loop.");
240
241
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
242
    if (retstat < 0) {
243
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
244
      MDBGLOG("smartcard","ERROR [rdpsc_open_args()]: \"%s\" (retstat = %d; cbdata->IoStatus.Fields.Sev = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
245
      fhandle = -1;
246
    }
247
248
    MDBGLOG("smartcard","rdpsc_open_args(): done. (fh = %d; retstat = %d)",fh,retstat);
249
250
    tc_mutex_unlock(lmutex);
251
    free_reqid(reqid);
252
253
    return retstat;
254
}
255
256
/** Read data from an open file
257
 *
258
 * Read should return exactly the number of bytes requested except
259
 * on EOF or error, otherwise the rest of the data will be
260
 * substituted with zeroes.  An exception to this is when the
261
 * 'direct_io' mount option is specified, in which case the return
262
 * value of the read system call will reflect the return value of
263
 * this operation.
264
 *
265
 * Changed in version 2.2
266
 */
267
// I don't fully understand the documentation above -- it doesn't
268
// match the documentation for the read() system call which says it
269
// can return with anything up to the amount of data requested. nor
270
// with the fusexmp code which returns the amount of data also
271
// returned by read.
272
273
int rdpsc_read_chunk(tbus fh, char * buf, size_t size) {
274
    int retstat = 0;
275
    int plen = 0;
276
    struct stream * s = NULL;
277
    int idx = 0;
278
    struct trans * pcon = (struct trans *)NULL;
279
    int rdpsc_opcode = 0x00000000;
280
    int reqid = -1;
281
    int uniqid = 0;
282
    tc_p lmutex = (tc_p)NULL;
283
    tc_p lcv = (tc_p)NULL;
284
    callback * cbdata = NULL;
285
    int mode = 0;
286
    size_t fsize = 0;
287
    uint32_t magic = 0;
288
    uint32_t crc32 = 0;
289
    uint32_t calc_crc32 = 0;
290
291
    tc_mutex_lock(mutex_smartcardop);
292
    get_reqid(&reqid);
293
    get_mutex(reqid, &lmutex);
294
    tc_mutex_lock(lmutex);
295
    tc_mutex_unlock(mutex_smartcardop);
296
297
    cbdata = &(g_reqids[reqid]);
298
    cbdata->userdata = buf;
299
300
    rdpsc_opcode = RDPSC_READ;
301
    uniqid = reqid;
302
303
    tc_mutex_lock(mutex_pcon);
304
    pcon = g_smartcard->ccon;
305
    pcon->callback_data = cbdata;
306
    s = trans_get_out_s(pcon, MAX_STREAM);
307
    out_uint32_le(s, pmagic);
308
    out_uint32_le(s, rdpsc_opcode);
309
    out_uint32_le(s, 4);
310
    out_uint32_le(s, fh);
311
    out_uint32_le(s, uniqid);
312
    out_uint32_le(s, crc32);
313
    out_uint32_le(s, size);
314
    s_mark_end(s);
315
    fsize = s->end - s->data;
316
    g_hexdump_file("/tmp/taskq_smartcard_read_chunk_cmd.hexdump", s->data, fsize);
317
    trans_force_write(pcon);
318
    g_memset(s->data,0,sizeof(char)*MAX_STREAM);
319
    tc_mutex_unlock(mutex_pcon);
320
    DBGLOG("smartcard","sent.");
321
322
    DBGLOG("smartcard"," Entering wait loop...");
323
    get_cv(reqid,&lcv);
324
    tc_cond_wait(lcv,lmutex);
325
    DBGLOG("smartcard"," Finished.");
326
327
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
328
    if (retstat < 0) {
329
      const char * nterr = (const char *)ntstatus_string(cbdata->IoStatus.Value);
330
      MDBGLOG("smartcard","ERROR [rdpsc_read_chunk()]: \"%s\" (retstat = %d; cbdata->IoStatus.Value = 0x%8.8x)",nterr,retstat,cbdata->IoStatus.Value);
331
      //retstat = 0;
332
    }
333
    else {
334
      retstat = cbdata->length;
335
    }
336
    g_hexdump_file("/tmp/taskq_smartcard_read_chunk_result.hexdump", cbdata->userdata, cbdata->length);
337
    g_memset(cbdata,0,sizeof(callback));
338
339
    tc_mutex_unlock(lmutex);
340
    free_reqid(reqid);
341
342
    return retstat;
343
}
344
345
int rdpsc_read(tbus fh, char * buf, size_t size) {
346
    #ifndef CHUNK_SIZE
347
    #define CHUNK_SIZE 4096
348
    #endif
349
    int retstat = 0;
350
    struct stream * s = NULL;
351
    int idx = 0;
352
    struct trans * pcon = (struct trans *)NULL;
353
    int rdpsc_opcode = 0x00000000;
354
    int reqid = -1;
355
    int uniqid = 0;
356
    tc_p lmutex = (tbus)NULL;
357
    tc_p lcv = (tbus)NULL;
358
    callback * cbdata = NULL;
359
    int mode = 0;
360
    int chunks = 0;
361
    char * tpos = NULL;
362
    off_t toffset = 0;
363
    size_t tsize = 0;
364
    uint64_t tally = 0;
365
366
    MDBGLOG("smartcard","rdpsc_read(): fh = %d; size = %d",fh,size);
367
368
    chunks = (size == 0) ? 0 : 1;
369
    if (size > CHUNK_SIZE) {
370
      chunks = ((size % CHUNK_SIZE) == 0) ? size / CHUNK_SIZE : (size / CHUNK_SIZE) + 1;
371
    }
372
373
    for (idx = 0; idx < chunks; idx++) {
374
      tpos = buf + (idx * CHUNK_SIZE);
375
      toffset = 0;
376
      tsize = (idx == (chunks - 1) && (size % CHUNK_SIZE) != 0) ? size % CHUNK_SIZE : CHUNK_SIZE;
377
      retstat = rdpsc_read_chunk(fh,tpos,tsize);
378
      if (retstat < 0) {
379
	break;
380
      }
381
      else {
382
	tally += retstat;
383
      }
384
    }
385
    if (retstat > -1) {
386
      retstat = tally;
387
    }
388
389
    return retstat;
390
}
391
392
/** Write data to an open file
393
 *
394
 * Write should return exactly the number of bytes requested
395
 * except on error.  An exception to this is when the 'direct_io'
396
 * mount option is specified (see read operation).
397
 *
398
 * Changed in version 2.2
399
 */
400
int rdpsc_write_chunk(tbus fh, const char * buf, size_t size) {
401
    int retstat = 0;
402
    struct stream * s = NULL;
403
    int idx = 0;
404
    int fsize = 0;
405
    struct trans * pcon = (struct trans *)NULL;
406
    int rdpsc_opcode = 0x00000000;
407
    int reqid = -1;
408
    int uniqid = 0;
409
    tc_p lmutex = (tbus)NULL;
410
    tc_p lcv = (tbus)NULL;
411
    callback * cbdata = NULL;
412
    uint32_t magic = 0;
413
    uint32_t crc32 = 0;
414
    uint32_t calc_crc32 = 0;
415
416
    tc_mutex_lock(mutex_smartcardop);
417
    get_reqid(&reqid);
418
    get_mutex(reqid, &lmutex);
419
    tc_mutex_lock(lmutex);
420
    tc_mutex_unlock(mutex_smartcardop);
421
422
    cbdata = &(g_reqids[reqid]);
423
    cbdata->userdata = (char *)buf;
424
425
    rdpsc_opcode = RDPSC_WRITE;
426
    uniqid = reqid;
427
428
    tc_mutex_lock(mutex_pcon);
429
    pcon = g_smartcard->ccon;
430
    pcon->callback_data = cbdata;
431
    s = trans_get_out_s(pcon, MAX_STREAM);
432
    out_uint32_le(s, pmagic);
433
    out_uint32_le(s, rdpsc_opcode);
434
    out_uint32_le(s, size);
435
    out_uint32_le(s, fh);
436
    out_uint32_le(s, uniqid);
437
    out_uint32_le(s, crc32);
438
    if (size > 0) {
439
      out_uint8a(s, buf, size);
440
    }
441
    s_mark_end(s);
442
    fsize = s->end - s->data;
443
    g_hexdump_file("/tmp/taskq_smartcard_write_chunk_cmd.hexdump", s->data, fsize);
444
    trans_force_write(pcon);
445
    g_memset(s->data,0,sizeof(char)*MAX_STREAM);
446
    tc_mutex_unlock(mutex_pcon);
447
    DBGLOG("smartcard","sent.");
448
449
    DBGLOG("smartcard"," Entering wait loop...");
450
    get_cv(reqid,&lcv);
451
    tc_cond_wait(lcv,lmutex);
452
    DBGLOG("smartcard"," Finished.");
453
454
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
455
    if (retstat < 0) {
456
      MDBGLOG("smartcard","ERROR [rdpsc_write_chunk()]: retstat = %d; cbdata->IoStatus.Value = %d",retstat,cbdata->IoStatus.Value);
457
    }
458
    else {
459
      retstat = cbdata->length;
460
    }
461
    g_hexdump_file("/tmp/taskq_smartcard_write_chunk_result.hexdump", cbdata->userdata, cbdata->length);
462
    g_memset(cbdata,0,sizeof(callback));
463
464
    tc_mutex_unlock(lmutex);
465
    free_reqid(reqid);
466
467
    return retstat;
468
}
469
470
int rdpsc_write(tbus fh, const char * buf, size_t size) {
471
    #ifndef CHUNK_SIZE
472
    #define CHUNK_SIZE 4096
473
    #endif
474
    int retstat = 0;
475
    struct stream * s = NULL;
476
    int idx = 0;
477
    int fsize = 0;
478
    struct trans * pcon = (struct trans *)NULL;
479
    int rdpsc_opcode = 0x00000000;
480
    int reqid = -1;
481
    int uniqid = 0;
482
    tc_p lmutex = (tbus)NULL;
483
    tc_p lcv = (tbus)NULL;
484
    callback * cbdata = NULL;
485
    int mode = 0;
486
    int chunks = 0;
487
    char * tpos = (BYTE *)NULL;
488
    off_t toffset = 0;
489
    size_t tsize = 0;
490
    uint64_t tally = 0;
491
492
    chunks = (size == 0) ? 0 : 1;
493
    if (size > CHUNK_SIZE) {
494
      chunks = ((size % CHUNK_SIZE) == 0) ? size / CHUNK_SIZE : (size / CHUNK_SIZE) + 1;
495
    }
496
497
    for (idx = 0; idx < chunks; idx++) {
498
      tpos = (char *)buf + (idx * CHUNK_SIZE);
499
      tsize = (idx == (chunks - 1) && (size % CHUNK_SIZE) != 0) ? size % CHUNK_SIZE : CHUNK_SIZE;
500
      retstat = rdpsc_write_chunk(fh,tpos,tsize);
501
      if (retstat < 0) {
502
	break;
503
      }
504
      else {
505
	tally += retstat;
506
      }
507
    }
508
    if (retstat > -1) {
509
      retstat = tally;
510
    }
511
512
    return retstat;
513
}
514
515
/** Release an open file
516
 *
517
 */
518
int rdpsc_release(tbus fh) {
519
    int retstat = 0;
520
    struct stream * s = NULL;
521
    int idx = 0;
522
    struct trans * pcon = (struct trans *)NULL;
523
    int rdpsc_opcode = 0x00000000;
524
    int size = 0x00000000;
525
    rdpsc_data rdata;
526
    int uniqid = 0;
527
    int reqid = -1;
528
    callback * cbdata = NULL;
529
    tc_p lmut = (tc_p)NULL;
530
    tc_p lcv = (tc_p)NULL;
531
    uint32_t magic = 0;
532
    uint32_t crc32 = 0;
533
    uint32_t calc_crc32 = 0;
534
535
    tc_mutex_lock(mutex_smartcardop);
536
    get_reqid(&reqid);
537
    get_mutex(reqid,&lmut);
538
    tc_mutex_lock(lmut);
539
    tc_mutex_unlock(mutex_smartcardop);
540
541
    MDBGLOG("smartcard","\n\nrdpsc_release(fh=\"%d\")\n",fh);
542
    g_memset(&rdata,0,sizeof(rdpsc_data));
543
544
    rdpsc_opcode = RDPSC_CLOSE;
545
    uniqid = reqid;
546
    cbdata = &(g_reqids[reqid]);
547
    cbdata->FileId = fh;
548
549
    tc_mutex_lock(mutex_pcon);
550
    pcon = g_smartcard->ccon;
551
    pcon->callback_data = cbdata;
552
    s = trans_get_out_s(pcon, MAX_STREAM);
553
    out_uint32_le(s, pmagic);
554
    out_uint32_le(s, rdpsc_opcode);
555
    out_uint32_le(s, size);
556
    out_uint32_le(s, fh);
557
    out_uint32_le(s, uniqid);
558
    out_uint32_le(s, crc32);
559
    s_mark_end(s);
560
    size = s->end - s->data;
561
    MDBGLOG("smartcard"," ** rdpsc_release(): sending [g_fd = %d]", g_fd);
562
    trans_force_write(pcon);
563
    DBGLOG("smartcard","sent.");
564
    g_hexdump_file("/tmp/taskq_smartcard_release.hexdump", s->data, size);
565
    g_memset(s->data,0,MAX_STREAM);
566
    tc_mutex_unlock(mutex_pcon);
567
568
    get_cv(reqid,&lcv);
569
    DBGLOG("smartcard"," Waiting...");
570
    tc_cond_wait(lcv,lmut);
571
    DBGLOG("smartcard"," Done.");
572
573
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
574
    if (retstat < 0) {
575
	char * nterr = ntstatus_string(cbdata->IoStatus.Value);
576
	//retstat = rdpsc_error("rdpsc_release lstat");
577
	MDBGLOG("smartcard","ERROR [rdpsc_release()]: \"%s\" (retstat = %d)",nterr,retstat);
578
    }
579
580
    MDBGLOG("smartcard","rdpsc_release(): done. ()");
581
582
    tc_mutex_unlock(lmut);
583
    free_reqid(reqid);
584
585
    return retstat;
586
}
587
588
/*
589
 *
590
 * Ioctl
591
 *
592
 */
593
int rdpsc_ioctl(tbus fh, int cmd, size_t argslen, void * args, size_t buflen, void * buf) {
594
    int retstat = 0;
595
    struct stream * s = NULL;
596
    struct trans * pcon = (struct trans *)NULL;
597
    int rdpsc_opcode = 0x00000000;
598
    int size = 0x00000000;
599
    rdpsc_data rdata;
600
    tc_p lmutex = (tbus)NULL;
601
    tc_p lcv = (tbus)NULL;
602
    callback * cbdata = NULL;
603
    int reqid = -1;
604
    int uniqid = 0;
605
    uint32_t magic = 0;
606
    uint32_t crc32 = 0;
607
    uint32_t calc_crc32 = 0;
608
609
    tc_mutex_lock(mutex_smartcardop);
610
    get_reqid(&reqid);
611
    get_mutex(reqid, &lmutex);
612
    tc_mutex_lock(lmutex);
613
    tc_mutex_unlock(mutex_smartcardop);
614
615
    MDBGLOG("smartcard","\n\nrdpsc_ioctl (fh=\"%d\"; argslen=\"%d\"; buflen=\"%d\")\n",fh,argslen,buflen);
616
617
    g_memset(&rdata,0,sizeof(rdpsc_data));
618
619
    get_cv(reqid, &lcv);
620
    cbdata = &(g_reqids[reqid]);
621
622
    rdpsc_opcode = RDPSC_IOCTL;
623
    uniqid = reqid;
624
    size = argslen;
625
626
    tc_mutex_lock(mutex_pcon);
627
    pcon = g_smartcard->ccon;
628
    pcon->callback_data = cbdata;
629
    s = trans_get_out_s(pcon, MAX_STREAM);
630
    out_uint32_le(s, pmagic);
631
    out_uint32_le(s, rdpsc_opcode);
632
    out_uint32_le(s, size + 4);
633
    out_uint32_le(s, fh);
634
    out_uint32_le(s, uniqid);
635
    out_uint32_le(s, crc32);
636
    out_uint32_le(s, cmd);
637
    if (argslen > 0) {
638
      out_uint8a(s, (char *)args, argslen);
639
    }
640
    s_mark_end(s);
641
    size = s->end - s->data;
642
643
    g_hexdump_file("/tmp/taskq_smartcard_ioctl.hexdump", s->data, size);
644
    MDBGLOG("smartcard"," ** rdpsc_ioctl(): sending [g_fd = %d; fh = %d; size = %d]", g_fd, argslen, size);
645
    trans_force_write(pcon);
646
    g_memset(s->data,0,MAX_STREAM);
647
    DBGLOG("smartcard","sent.");
648
    tc_mutex_unlock(mutex_pcon);
649
650
    DBGLOG("smartcard","entering g_obj_wait loop:");
651
    tc_cond_wait(lcv, lmutex);
652
    DBGLOG("smartcard","exiting g_obj_wait loop.");
653
654
    retstat = ntstatus_to_errcode(cbdata->IoStatus.Value);
655
    if (retstat < 0) {
656
      char * nterr = ntstatus_string(cbdata->IoStatus.Value);
657
      MDBGLOG("smartcard","ERROR [rdpsc_ioctl()]: \"%s\" (cbdata->IoStatus.Fields.Sev == STATUS_SEVERITY_ERROR)",nterr);
658
    }
659
660
    DBGLOG("smartcard","rdpsc_ioctl(): done.");
661
662
    tc_mutex_unlock(lmutex);
663
    free_reqid(reqid);
664
665
    return retstat;
666
}
667
668
669
/*****************************************************************************/
670
/*****		child process-related section				******/
671
/*****************************************************************************/
672
673
674
/*****************************************************************************/
675
static int APP_CC
676
parent_data_in(struct trans * trans) {
677
  struct stream * s = (struct stream *)NULL;
678
  int rdpsc_opcode = 0;
679
  int rdpsc_reply = 0;
680
  int size = 0;
681
  int error = 0;
682
  int fault = 0;
683
  int fhandle = 0;
684
  int uniqid = 0;
685
  int fdone = 0;
686
  uint32_t magic = 0;
687
  uint32_t crc32 = 0;
688
  uint32_t calc_crc32 = 0;
689
  BYTE buf[MAX_STREAM];
690
691
  DBGLOG("smartcard","parent_data_in(): called");
692
693
  g_memset((BYTE *)buf,0,sizeof(BYTE)*MAX_STREAM);
694
695
  if (trans == 0)
696
  {
697
    return 0;
698
  }
699
  tc_mutex_lock(mutex_pcon);
700
  s = (struct stream *)trans_get_in_s(trans);
701
  in_uint32_le(s, magic);
702
  in_uint32_le(s, rdpsc_reply);
703
  in_uint32_le(s, size);
704
  in_uint32_le(s, fhandle);
705
  in_uint32_le(s, uniqid);
706
  in_uint32_le(s, crc32);
707
  if (size > 0) {
708
    error = trans_force_read(trans, size);
709
  }
710
  if (error == 0)
711
  {
712
    /* the entire message block has been read in, so process it: */
713
    fault = ((rdpsc_reply & RDPSC_ERROR) == 0) ? 0 : 1;
714
    rdpsc_opcode = rdpsc_reply & (~(RDPSC_REPLY | RDPSC_ERROR));
715
    MDBGLOG("smartcard"," ** parent_data_in(): rdpsc_opcode = 0x%8.8x; rdpsc_reply = 0x%8.8x; fault = %d; uniqid = %d",rdpsc_opcode,rdpsc_reply,fault,uniqid);
716
    if (fault > 0) {
717
      NTSTATUS iostatus = { .Value = 0x00000000 };
718
      int reqid = -1;
719
      callback * cbdata = NULL;
720
      tc_p lmut = (tc_p)NULL;
721
      tc_p lcv = (tc_p)NULL;
722
      char * nterr = (char *)NULL;
723
724
      tc_mutex_lock(mutex_smartcardop);
725
      in_uint32_le(s, iostatus.Value);
726
727
      nterr = ntstatus_string(iostatus.Value);
728
      MDBGLOG("smartcard"," --> FAULT: \"%s\" (status = 0x%8.8x)",nterr,iostatus.Value);
729
      cbdata = &(g_reqids[uniqid]);
730
      reqid = cbdata->opid;
731
      if (reqid > -1) {
732
        get_mutex(reqid, &lmut);
733
	tc_mutex_lock(lmut);
734
        tc_mutex_unlock(mutex_smartcardop);
735
	cbdata->IoStatus.Value = iostatus.Value;
736
        get_cv(reqid, &lcv);
737
	tc_cond_signal(lcv);
738
      }
739
      else {
740
	lmut = mutex_smartcardop;
741
      }
742
      tc_mutex_unlock(lmut);
743
    }
744
    else switch(rdpsc_opcode) {
745
      case RDPSC_OPEN:
746
	DBGLOG("smartcard"," ^^ (RDPSC_OPEN)");
747
	{
748
	  DR_DRIVE_CREATE_RSP iorsp;
749
	  int reqid = -1;
750
	  callback * cbdata = NULL;
751
	  tc_p lmut = (tbus)NULL;
752
	  tc_p lcv = (tbus)NULL;
753
	  tc_mutex_lock(mutex_smartcardop);
754
	  cbdata = &(g_reqids[uniqid]);
755
	  reqid = cbdata->opid;
756
	  get_mutex(reqid, &lmut);
757
	  tc_mutex_lock(lmut);
758
	  tc_mutex_unlock(mutex_smartcardop);
759
	  get_cv(reqid, &lcv);
760
	  construct_DR_DRIVE_CREATE_RSP(&iorsp);
761
	  if (size > 0 && size < MAX_STREAM) {
762
	    get_DR_DRIVE_CREATE_RSP(&iorsp, s);
763
	  }
764
	  cbdata->FileId = iorsp.DeviceCreateResponse.FileId;
765
	  MDBGLOG("smartcard"," --> FileId = %d; fhandle = %d",cbdata->FileId,fhandle);
766
	  {
767
	    int tsize = 0;
768
	    char vdata[MAX_STREAM];
769
	    struct stream vs;
770
	    struct stream * v = &vs;
771
	    g_memset(&vdata,0,sizeof(char)*MAX_STREAM);
772
	    g_memset(v,0,sizeof(struct stream));
773
	    v->data = (char *)(&vdata);
774
	    v->p = v->data;
775
	    v->end = v->data;
776
	    v->size = MAX_STREAM;
777
	    send_DR_DRIVE_CREATE_RSP(&iorsp, v);
778
	    s_mark_end(v);
779
	    tsize = v->end - v->data;
780
	    g_hexdump_file("/tmp/taskq_smartcard_open_reply.hexdump",v->data,tsize);
781
	  }
782
	  tc_cond_signal(lcv);
783
	  tc_mutex_unlock(lmut);
784
	}
785
	break;
786
      case RDPSC_READ:
787
	DBGLOG("smartcard"," ^^ (RDPSC_READ)");
788
	{
789
	  DR_DRIVE_READ_RSP iorsp;
790
	  int reqid = -1;
791
	  callback * cbdata = (callback *)NULL;
792
	  tc_p lmut = (tbus)NULL;
793
	  tc_p lcv = (tbus)NULL;
794
	  tc_mutex_lock(mutex_smartcardop);
795
	  cbdata = &(g_reqids[uniqid]);
796
	  reqid = cbdata->opid;
797
	  get_mutex(reqid, &lmut);
798
	  tc_mutex_lock(lmut);
799
	  tc_mutex_unlock(mutex_smartcardop);
800
	  construct_DR_READ_RSP(&iorsp);
801
	  iorsp.ReadData = cbdata->userdata;
802
	  get_DR_READ_RSP(&iorsp, s);
803
	  cbdata->length = iorsp.Length;
804
	  get_cv(reqid,&lcv);
805
	  tc_cond_signal(lcv);
806
	  tc_mutex_unlock(lmut);
807
	  MDBGLOG("smartcard"," ^^ (RDPSC_READ): iorsp.Length = %d; iorsp.ReadData = \"%s\"",iorsp.Length,iorsp.ReadData);
808
	}
809
	break;
810
      case RDPSC_WRITE:
811
	DBGLOG("smartcard"," ^^ (RDPSC_WRITE)");
812
	{
813
	  DR_DRIVE_WRITE_RSP iorsp;
814
	  int reqid = -1;
815
	  callback * cbdata = (callback *)NULL;
816
	  tc_p lmut = (tbus)NULL;
817
	  tc_p lcv = (tbus)NULL;
818
	  tc_mutex_lock(mutex_smartcardop);
819
	  cbdata = &(g_reqids[uniqid]);
820
	  reqid = cbdata->opid;
821
	  get_mutex(reqid, &lmut);
822
	  tc_mutex_lock(lmut);
823
	  tc_mutex_unlock(mutex_smartcardop);
824
	  construct_DR_WRITE_RSP(&iorsp);
825
	  get_DR_WRITE_RSP(&iorsp, s);
826
	  cbdata->length = iorsp.Length;
827
	  get_cv(reqid,&lcv);
828
	  tc_cond_signal(lcv);
829
	  tc_mutex_unlock(lmut);
830
	}
831
	break;
832
      case RDPSC_IOCTL:
833
	DBGLOG("smartcard"," ^^ (RDPSC_IOCTL)");
834
	{
835
	  DR_CONTROL_RSP iorsp;
836
	  int reqid = -1;
837
	  callback * cbdata = (callback *)NULL;
838
	  tc_p lmut = (tbus)NULL;
839
	  tc_p lcv = (tbus)NULL;
840
	  tc_mutex_lock(mutex_smartcardop);
841
	  cbdata = &(g_reqids[uniqid]);
842
	  reqid = cbdata->opid;
843
	  get_mutex(reqid, &lmut);
844
	  tc_mutex_lock(lmut);
845
	  tc_mutex_unlock(mutex_smartcardop);
846
	  construct_DR_CONTROL_RSP(&iorsp);
847
	  iorsp.OutputBuffer = cbdata->userdata;
848
	  get_DR_CONTROL_RSP(&iorsp, s);
849
	  cbdata->length = iorsp.OutputBufferLength;
850
	  get_cv(reqid,&lcv);
851
	  tc_cond_signal(lcv);
852
	  tc_mutex_unlock(lmut);
853
	  MDBGLOG("smartcard"," ^^ (RDPSC_IOCTL): iorsp.OutputBufferLength = %d;",iorsp.OutputBufferLength);
854
	}
855
	break;
856
      case RDPSC_CLOSE:
857
	DBGLOG("smartcard"," ^^ (RDPSC_CLOSE)");
858
	{
859
	  int reqid = -1;
860
	  callback * cbdata = (callback *)NULL;
861
	  tc_p lmut = (tbus)NULL;
862
	  tc_p lcv = (tbus)NULL;
863
	  tc_mutex_lock(mutex_smartcardop);
864
	  cbdata = &(g_reqids[uniqid]);
865
	  reqid = cbdata->opid;
866
	  get_mutex(reqid, &lmut);
867
	  tc_mutex_lock(lmut);
868
	  tc_mutex_unlock(mutex_smartcardop);
869
	  get_cv(reqid,&lcv);
870
	  tc_cond_signal(lcv);
871
	  tc_mutex_unlock(lmut);
872
	}
873
	break;
874
      case RDPSC_INIT:
875
	DBGLOG("smartcard"," ^^ (RDPSC_INIT)");
876
	{
877
	  int reqid = -1;
878
	  callback * cbdata = (callback *)NULL;
879
	  filelist * lst = (filelist *)NULL;
880
	  tc_p lmut = (tbus)NULL;
881
	  tc_p lcv = (tbus)NULL;
882
	}
883
	break;
884
      case RDPSC_DESTROY:
885
	DBGLOG("smartcard"," ^^ (RDPSC_DESTROY)");
886
	exit(0);
887
	break;
888
      case RDPSC_ERROR:
889
	DBGLOG("smartcard"," ^^ (RDPSC_ERROR)");
890
	exit(0);
891
	break;
892
    }
893
  }
894
  tc_mutex_unlock(mutex_pcon);
895
  return error;
896
}
897
898
typedef struct _handle_smartcard_loop_args {
899
	rdpsc *		smartcard;
900
	struct trans *		pcon;
901
	tbus			objs[2];
902
	int			num_objs;
903
	int			timeout;
904
	int			check_parent;
905
	int			check_device;
906
} handle_smartcard_loop_args;
907
908
static void * APP_CC
909
loop_parent_sc(void * inargs) {
910
  handle_smartcard_loop_args * largs = (handle_smartcard_loop_args *)inargs;
911
  rdpsc * smartcard = largs->smartcard;
912
  struct trans * pcon = largs->pcon;
913
  tbus * objs = (tbus *)(largs->objs);
914
  int num_objs = largs->num_objs;
915
  int timeout = largs->timeout;
916
  int check_parent = largs->check_parent;
917
  int check_device = largs->check_device;
918
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_parent > 0) {
919
    /* handle any inbound communication from the parent process: */
920
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
921
      if ((check_parent > 0) && g_is_wait_obj_set(objs[0])) {
922
	tc_mutex_lock(mutex_parent);
923
	if (trans_check_wait_objs(pcon) != 0) {
924
	  DBGLOG("smartcard","ERROR [loop_parent_sc()]: ");
925
	  //rv = -1;
926
	  break;
927
	}
928
	tc_mutex_unlock(mutex_parent);
929
      }
930
    }
931
  }
932
  tc_thread_exit(NULL);
933
}
934
935
static void * APP_CC
936
loop_device_sc(void * inargs) {
937
  handle_smartcard_loop_args * largs = (handle_smartcard_loop_args *)inargs;
938
  rdpsc * smartcard = largs->smartcard;
939
  struct trans * pcon = largs->pcon;
940
  tbus * objs = (tbus *)(largs->objs);
941
  int num_objs = largs->num_objs;
942
  int timeout = largs->timeout;
943
  int check_parent = largs->check_parent;
944
  int check_device = largs->check_device;
945
  if (inargs != NULL && objs != NULL && num_objs > 0 && check_device > 0) {
946
    /* handle communication from pseudo-device (i.e., the artificial serial or parallel smartcard on the server): */
947
    while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) {
948
      if ((check_device > 0) && ((num_objs == 2 && g_is_wait_obj_set(objs[1])) || (num_objs == 1 && g_is_wait_obj_set(objs[0])))) {
949
	tc_mutex_lock(mutex_device);
950
	rdpsc_cycle(smartcard);
951
	tc_mutex_unlock(mutex_device);
952
      }
953
    }
954
  }
955
  tc_thread_exit(NULL);
956
}
957
958
/*****************************************************************************/
959
static int APP_CC
960
rdpsc_cycle(rdpsc * smartcard) {
961
  int rv = 0;
962
  return rv;
963
}
964
965
/*****************************************************************************/
966
int APP_CC
967
handle_smartcard(tbus sck, rdpsc * smartcard) {
968
  int rv = 0;
969
  int brk = 0;
970
  struct trans * pcon = (struct trans *)NULL;
971
  tbus objs[2] = { -1, -1 };
972
  int num_objs = 0;
973
  int timeout = 0;
974
  int check_parent = 0;
975
  int check_device = 0;
976
  handle_smartcard_loop_args largs;
977
  tc_thread_t thread_parent;
978
  tc_thread_t thread_device;
979
980
  MDBGLOG("smartcard","handle_smartcard(): sck = %d",sck);
981
  g_memset(&largs,0,sizeof(handle_smartcard_loop_args));
982
  g_memset(&thread_parent,0,sizeof(tbus));
983
  g_memset(&thread_device,0,sizeof(tbus));
984
985
  mut = (tc_p)&g_mutex;
986
  mutex_pcon = (tc_p)&g_mutex_pcon;
987
  mutex_smartcard = (tc_p)&g_mutex_smartcard;
988
  mutex_smartcardop = (tc_p)&g_mutex_smartcardop;
989
  mutex_parent = (tc_p)&g_mutex_parent;
990
  mutex_device = (tc_p)&g_mutex_device;
991
  mutex_reqid = (tc_p)&g_mutex_reqid;
992
  tc_mutex_init(mut,NULL);
993
  tc_mutex_init(mutex_pcon,NULL);
994
  tc_mutex_init(mutex_smartcard,NULL);
995
  tc_mutex_init(mutex_smartcardop,NULL);
996
  tc_mutex_init(mutex_parent,NULL);
997
  tc_mutex_init(mutex_device,NULL);
998
  tc_mutex_init(mutex_reqid,NULL);
999
1000
  tc_mutex_lock(mutex_pcon);
1001
  tc_mutex_lock(mutex_smartcard);
1002
1003
  init_reqids();
1004
1005
    /* set up pcon as a transmission channel to the parent */
1006
  pcon = (struct trans *)trans_create((int)2, (int)MAX_STREAM, (int)MAX_STREAM);
1007
  pcon->trans_data_in = &parent_data_in;
1008
  pcon->header_size = 24;
1009
  rv = trans_attach(pcon, sck);
1010
  pcon->sck = sck;
1011
  smartcard->ccon = pcon;
1012
1013
  tc_mutex_unlock(mutex_pcon);
1014
  tc_mutex_unlock(mutex_smartcard);
1015
1016
  if (rv > -1) {
1017
1018
    tc_mutex_lock(mutex_pcon);
1019
    tc_mutex_lock(mutex_smartcard);
1020
1021
    /* add pcon to the set of monitored channels */
1022
    if (pcon != NULL && pcon->sck > 0) {
1023
      objs[num_objs] = pcon->sck;
1024
      num_objs++;
1025
      check_parent = 1;
1026
    }
1027
1028
    /* add the appropriate ttyS* file descriptor to the set of monitored channels */
1029
    if (smartcard->fd > 0) {
1030
      objs[num_objs] = smartcard->fd;
1031
      num_objs++;
1032
      check_device = 1;
1033
    }
1034
1035
    tc_mutex_unlock(mutex_pcon);
1036
    tc_mutex_unlock(mutex_smartcard);
1037
1038
    /* monitor the above channels for input and respond appropriately */
1039
    if (num_objs > 0 && objs[0] > -1) {
1040
1041
      tc_mutex_lock(mutex_pcon);
1042
      tc_mutex_lock(mutex_smartcard);
1043
1044
      largs.smartcard = smartcard;
1045
      largs.pcon = pcon;
1046
      largs.objs[0] = objs[0];
1047
      largs.objs[1] = objs[1];
1048
      largs.num_objs = num_objs;
1049
      largs.timeout = timeout;
1050
      largs.check_parent = check_parent;
1051
      largs.check_device = check_device;
1052
1053
      tc_mutex_unlock(mutex_pcon);
1054
      tc_mutex_unlock(mutex_smartcard);
1055
1056
1057
      if (objs != NULL && num_objs > 0 && (check_parent > 0 || check_device > 0)) {
1058
	tc_thread_init(&thread_parent,&loop_parent_sc,&largs);
1059
	tc_thread_init(&thread_device,&loop_device_sc,&largs);
1060
	tc_thread_join(thread_parent,NULL);
1061
	tc_thread_join(thread_device,NULL);
1062
      }
1063
    }
1064
  }
1065
1066
  return rv;
1067
}
1068
1069
static int APP_CC get_reqid(int * inarg) {
1070
  int rv = 0;
1071
  if (inarg == NULL) {
1072
    rv = -1;
1073
  }
1074
  else {
1075
    *inarg = -1;
1076
    tc_mutex_lock(mutex_reqid);
1077
    for (rv = 1; rv < MAX_REQID; rv++) {
1078
      if (g_reqids[rv].opid == -1) {
1079
	*inarg = rv;
1080
	g_reqids[rv].opid = rv;
1081
	tc_mutex_init(&(g_reqids[rv].mutex),NULL);
1082
	tc_cond_create(&(g_reqids[rv].cv),NULL);
1083
	break;
1084
      }
1085
    }
1086
    tc_mutex_unlock(mutex_reqid);
1087
  }
1088
  return rv;
1089
}
1090
1091
static int APP_CC free_reqid(int inarg) {
1092
  int rv = 0;
1093
  if (inarg < 0 || inarg > MAX_REQID) {
1094
    rv = -1;
1095
  }
1096
  else if (g_reqids[inarg].opid > -1 && g_reqids[inarg].opid <= MAX_REQID) {
1097
    tc_mutex_lock(mutex_reqid);
1098
    tc_mutex_deinit(&(g_reqids[inarg].mutex));
1099
    tc_cond_deinit(&(g_reqids[inarg].cv));
1100
    g_memset(&(g_reqids[inarg]),0,sizeof(callback));
1101
    g_reqids[inarg].opid = -1;
1102
    tc_mutex_unlock(mutex_reqid);
1103
  }
1104
  return rv;
1105
}
1106
1107
static int APP_CC init_reqids() {
1108
  int rv = 0;
1109
  tc_mutex_lock(mutex_reqid);
1110
  g_memset((callback *)g_reqids,0,sizeof(callback)*MAX_REQID);
1111
  for (rv = 0; rv < MAX_REQID; rv++) {
1112
    g_reqids[rv].opid = -1;
1113
  }
1114
  tc_mutex_unlock(mutex_reqid);
1115
  rv = 0;
1116
  return rv;
1117
}
1118
1119
static int APP_CC get_mutex(int reqid, tbus * inarg) {
1120
  int rv = 0;
1121
  
1122
  if (reqid >= 0 && reqid < MAX_REQID) {
1123
    tc_mutex_lock(mutex_reqid);
1124
    *inarg = (tbus)&(g_reqids[reqid].mutex);
1125
    tc_mutex_unlock(mutex_reqid);
1126
  }
1127
  else {
1128
    rv = -1;
1129
  }
1130
  return rv;
1131
}
1132
1133
static int APP_CC get_cv(int reqid, tbus* inarg) {
1134
  int rv = 0;
1135
  if (reqid >= 0 && reqid < MAX_REQID) {
1136
    tc_mutex_lock(mutex_reqid);
1137
    *inarg = (tbus)&(g_reqids[reqid].cv);
1138
    tc_mutex_unlock(mutex_reqid);
1139
  }
1140
  else {
1141
    rv = -1;
1142
  }
1143
  return rv;
1144
}
1145
1146
static char * APP_CC rdpsc_get_dircomponent(char * rv, const char * name) {
1147
  char * npos = (char *)NULL;
1148
1149
  if (name != NULL) {
1150
    npos = (char *)g_strrchr(name, (int)'/');
1151
    if (npos > 0) {
1152
      if (rv == NULL) {
1153
	rv = (char *)g_malloc(sizeof(char) * ((npos - name) + 1), 1);
1154
      }
1155
      g_strncpy(rv, name, (npos - name));
1156
    }
1157
  }
1158
1159
  return rv;
1160
}
1161
1162
/********************************************************/
1163
/*	refactor a filename into canonical form		*/
1164
/********************************************************/
1165
static void APP_CC rdpsc_clean_fname(char * name) {
1166
        char * p = (char *)NULL;
1167
	char * p2 = (char *)NULL;
1168
        int l = 0;
1169
        int modified = 1;
1170
	const char forbidden[] = {'/', '[', ']', ':', '|', '<', '>', '+', '=', ';', ',', '?', 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
1171
1172
        if (name == NULL) {
1173
	  return;
1174
	}
1175
1176
        MDBGLOG("smartcard","rdpsc_clean_fname() [%s]:\n", name);
1177
1178
	while (modified) {
1179
		modified = 0;
1180
		if ((p=strstr(name,"/./"))) {
1181
			modified = 1;
1182
			while (*p) {
1183
				p[0] = p[2];
1184
				p++;
1185
			}
1186
			MDBGLOG("smartcard", "\tclean 1 (/./) produced [%s]\n", name);
1187
		}
1188
		if ((p=strstr(name,"//"))) {
1189
			modified = 1;
1190
			while (*p) {
1191
				p[0] = p[1];
1192
				p++;
1193
			}
1194
			MDBGLOG("smartcard", "\tclean 2 (//) produced [%s]\n", name);
1195
		}
1196
		if (strcmp(name,"/../")==0) {
1197
			modified = 1;
1198
			name[1] = 0;
1199
			MDBGLOG("smartcard", "\tclean 3 (^/../$) produced [%s]\n", name);
1200
		}
1201
		if ((p=strstr(name,"/../"))) {
1202
			modified = 1;
1203
			for (p2 = (p > name ? p-1 : p); p2 > name; p2--) {
1204
				if (p2[0] == '/') {
1205
					break;
1206
				}
1207
			}
1208
			if (p2 > name) p2++;
1209
			while (*p2) {
1210
				p2[0] = p[3];
1211
				p2++;
1212
				p++;
1213
			}
1214
			MDBGLOG("smartcard", "\tclean 4 (/../) produced [%s]\n", name);
1215
		}
1216
1217
                if (strcmp(name,"/..")==0) {
1218
                        modified = 1;
1219
                        name[1] = 0;
1220
                        MDBGLOG("smartcard", "\tclean 5 (^/..$) produced [%s]\n", name);
1221
                }
1222
1223
                l = strlen(name);
1224
                p = l>=3?(name+l-3):name;
1225
                if (strcmp(p,"/..")==0) {
1226
                        modified = 1;
1227
                        for (p2=p-1;p2>name;p2--) {
1228
                                if (p2[0] == '/') break;
1229
                        }
1230
                        if (p2==name) {
1231
                                p[0] = '/';
1232
                                p[1] = 0;
1233
                        } else {
1234
                                p2[0] = 0;
1235
                        }
1236
                        MDBGLOG("smartcard", "\tclean 6 (/..) produced [%s]\n", name);
1237
                }
1238
1239
                l = strlen(name);
1240
                p = l>=2?(name+l-2):name;
1241
                if (strcmp(p,"/.")==0) {
1242
                        modified = 1;
1243
                        if (p == name) {
1244
                                p[1] = 0;
1245
                        } else {
1246
                                p[0] = 0;
1247
                        }
1248
                        MDBGLOG("smartcard", "\tclean 7 (/.) produced [%s]\n", name);
1249
                }
1250
1251
                if (strncmp(p=name,"./",2) == 0) {
1252
                        modified = 1;
1253
                        do {
1254
                                p[0] = p[2];
1255
                        } while (*p++);
1256
                        MDBGLOG("smartcard", "\tclean 8 (^./) produced [%s]\n", name);
1257
                }
1258
1259
                l = strlen(p=name);
1260
                if (l > 1 && p[l-1] == '/') {
1261
                        modified = 1;
1262
                        p[l-1] = 0;
1263
                        MDBGLOG("smartcard", "\tclean 9 (/) produced [%s]\n", name);
1264
                }
1265
        }
1266
1267
        MDBGLOG("smartcard","rdpsc_clean_fname() done [%s].\n", name);
1268
}
1269
1270
static int APP_CC ntstatus_to_errcode(DWORD ntstat) {
1271
  int retstat = 0;
1272
1273
  switch (ntstat) {
1274
	case 0:
1275
	  retstat = 0;
1276
	  break;
1277
	case STATUS_ACCESS_DENIED:
1278
	case STATUS_ACCESS_VIOLATION:
1279
	case STATUS_NETWORK_ACCESS_DENIED:
1280
	case STATUS_UNSUCCESSFUL:
1281
	  retstat = -EACCES;
1282
	  break;
1283
	case STATUS_GUARD_PAGE_VIOLATION:
1284
	case STATUS_INVALID_PARAMETER:
1285
	case STATUS_BAD_DEVICE_TYPE:
1286
	case STATUS_BAD_NETWORK_NAME:
1287
	case STATUS_INVALID_VOLUME_LABEL:
1288
	case STATUS_BAD_TOKEN_TYPE:
1289
	case STATUS_INVALID_GROUP_ATTRIBUTES:
1290
	case STATUS_BAD_MASTER_BOOT_RECORD:
1291
	case STATUS_INVALID_OPLOCK_PROTOCOL:
1292
	case STATUS_INVALID_INFO_CLASS:
1293
	case STATUS_INVALID_DEVICE_REQUEST:
1294
	case STATUS_INVALID_SYSTEM_SERVICE:
1295
	case STATUS_ILLEGAL_INSTRUCTION:
1296
	case STATUS_INVALID_LOCK_SEQUENCE:
1297
	case STATUS_INVALID_VIEW_SIZE:
1298
	case STATUS_INVALID_FILE_FOR_SECTION:
1299
	case STATUS_INVALID_DISPOSITION:
1300
	case STATUS_INVALID_UNWIND_TARGET:
1301
	case STATUS_INVALID_PORT_ATTRIBUTES:
1302
	case STATUS_INVALID_PARAMETER_MIX:
1303
	case STATUS_OBJECT_NAME_INVALID:
1304
	case STATUS_INVALID_VARIANT:
1305
	case STATUS_POWER_STATE_INVALID:
1306
	case STATUS_INVALID_DEVICE_OBJECT_PARAMETER:
1307
	case STATUS_INVALID_BLOCK_LENGTH:
1308
	  retstat = -EINVAL;
1309
	  break;
1310
#ifdef ENOMEDIUM
1311
	case STATUS_NO_MEDIA_IN_DEVICE:
1312
	case STATUS_UNRECOGNIZED_MEDIA:
1313
	  retstat = -ENOMEDIUM;
1314
	  break;
1315
#endif
1316
	case STATUS_SHARING_VIOLATION:
1317
	case STATUS_FILE_LOCK_CONFLICT:
1318
	case STATUS_LOCK_NOT_GRANTED:
1319
	case STATUS_SHARING_PAUSED:
1320
	case STATUS_SHARED_POLICY:
1321
	case STATUS_NOT_LOCKED:
1322
	case STATUS_PIPE_BUSY:
1323
	case STATUS_CONNECTION_IN_USE:
1324
	case STATUS_WAIT_FOR_OPLOCK:
1325
	  retstat = -EBUSY;
1326
	  break;
1327
	case STATUS_LOGON_FAILURE:
1328
	case STATUS_ACCOUNT_RESTRICTION:
1329
	case STATUS_ILL_FORMED_PASSWORD:
1330
	case STATUS_PASSWORD_RESTRICTION:
1331
	case STATUS_INVALID_LOGON_HOURS:
1332
	case STATUS_INVALID_WORKSTATION:
1333
	case STATUS_PASSWORD_EXPIRED:
1334
	case STATUS_ACCOUNT_DISABLED:
1335
	case STATUS_WRONG_PASSWORD:
1336
	case STATUS_SECTION_PROTECTION:
1337
	case STATUS_PRIVILEGE_NOT_HELD:
1338
	case STATUS_PRIVILEGED_INSTRUCTION:
1339
	case STATUS_PASSWORD_MUST_CHANGE:
1340
	case STATUS_ACCOUNT_LOCKED_OUT:
1341
	case STATUS_RESOURCE_NOT_OWNED:
1342
	case STATUS_LICENSE_VIOLATION:
1343
	case STATUS_LICENSE_QUOTA_EXCEEDED:
1344
	case STATUS_EVALUATION_EXPIRATION:
1345
	case STATUS_COPY_PROTECTION_FAILURE:
1346
	case STATUS_SMARTCARD_WRONG_PIN:
1347
	case STATUS_SMARTCARD_CARD_BLOCKED:
1348
	case STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED:
1349
	case STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT:
1350
	case STATUS_ACCESS_DISABLED_BY_POLICY_PATH:
1351
	case STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER:
1352
	case STATUS_ACCESS_DISABLED_BY_POLICY_OTHER:
1353
	case STATUS_CSS_AUTHENTICATION_FAILURE:
1354
	case STATUS_CSS_KEY_NOT_PRESENT:
1355
	case STATUS_CSS_KEY_NOT_ESTABLISHED:
1356
	case STATUS_INSUFFICIENT_LOGON_INFO:
1357
	  retstat = -EPERM;
1358
	  break;
1359
	case STATUS_DEVICE_DOES_NOT_EXIST:
1360
	case STATUS_DEVICE_NOT_CONNECTED:
1361
	case STATUS_DEVICE_POWER_FAILURE:
1362
	case STATUS_DEVICE_REMOVED:
1363
	case STATUS_PLUGPLAY_NO_DEVICE:
1364
	case STATUS_VOLUME_DISMOUNTED:
1365
	case STATUS_NOINTERFACE:
1366
	case STATUS_PARTITION_FAILURE:
1367
	  retstat = -ENODEV;
1368
	  break;
1369
	case STATUS_NO_MORE_FILES:
1370
	case STATUS_OBJECT_NAME_NOT_FOUND:
1371
	case STATUS_NOT_FOUND:
1372
	case STATUS_INVALID_PLUGPLAY_DEVICE_PATH:
1373
	case STATUS_NO_SUCH_FILE:
1374
	case STATUS_NETWORK_NAME_DELETED:
1375
	case STATUS_FILE_IS_OFFLINE:
1376
	case STATUS_MOUNT_POINT_NOT_RESOLVED:
1377
	  retstat = -ENOENT;
1378
	  break;
1379
	case STATUS_LOGON_SESSION_EXISTS:
1380
	case STATUS_DUPLICATE_NAME:
1381
	case STATUS_ALIAS_EXISTS:
1382
	case STATUS_ADDRESS_ALREADY_EXISTS:
1383
	case STATUS_DUPLICATE_OBJECTID:
1384
	case STATUS_OBJECTID_EXISTS:
1385
	  retstat = -EEXIST;
1386
	  break;
1387
	case STATUS_WRONG_VOLUME:
1388
	  retstat = -EXDEV;
1389
	  break;
1390
	case STATUS_BUFFER_TOO_SMALL:
1391
	case STATUS_SECTION_TOO_BIG:
1392
	case STATUS_SYSTEM_HIVE_TOO_LARGE:
1393
	  retstat = -E2BIG;
1394
	  break;
1395
	case STATUS_MEMORY_NOT_ALLOCATED:
1396
	case STATUS_NO_MEMORY:
1397
	case STATUS_INSUFFICIENT_RESOURCES:
1398
	case STATUS_INSUFF_SERVER_RESOURCES:
1399
	  retstat = -ENOMEM;
1400
	  break;
1401
	case STATUS_INVALID_HANDLE:
1402
	case STATUS_FILE_INVALID:
1403
	case STATUS_INVALID_PORT_HANDLE:
1404
	case STATUS_FILE_DELETED:
1405
	case STATUS_FILE_CLOSED:
1406
	case STATUS_FILE_CORRUPT_ERROR:
1407
	case STATUS_USER_MAPPED_FILE:
1408
	case STATUS_NOT_A_REPARSE_POINT:
1409
	case STATUS_DIRECTORY_IS_A_REPARSE_POINT:
1410
	case STATUS_FILE_NOT_ENCRYPTED:
1411
	case STATUS_FILE_ENCRYPTED:
1412
	case STATUS_CORRUPT_SYSTEM_FILE:
1413
	case STATUS_HANDLE_NOT_CLOSABLE:
1414
	  retstat = -EBADF;
1415
	  break;
1416
	case STATUS_FILES_OPEN:
1417
	  retstat = -EMFILE;
1418
	  break;
1419
	case STATUS_TOO_MANY_OPENED_FILES:
1420
	  retstat = -ENFILE;
1421
	  break;
1422
	case STATUS_PIPE_NOT_AVAILABLE:
1423
	case STATUS_INVALID_PIPE_STATE:
1424
	case STATUS_PIPE_BROKEN:
1425
	case STATUS_PIPE_EMPTY:
1426
	  retstat = -EPIPE;
1427
	  break;
1428
	case STATUS_DISK_FULL:
1429
	case STATUS_NO_LOG_SPACE:
1430
	case STATUS_LOG_FILE_FULL:
1431
	case STATUS_NO_SPOOL_SPACE:
1432
	case STATUS_PRINT_QUEUE_FULL:
1433
	case STATUS_DESTINATION_ELEMENT_FULL:
1434
	  retstat = -ENOSPC;
1435
	  break;
1436
	case STATUS_MEDIA_WRITE_PROTECTED:
1437
	  retstat = -EROFS;
1438
	  break;
1439
	case STATUS_DIRECTORY_NOT_EMPTY:
1440
	  retstat = -ENOTEMPTY;
1441
	  break;
1442
	case STATUS_RETRY:
1443
	  retstat = -EAGAIN;
1444
	  break;
1445
	case STATUS_OBJECT_PATH_NOT_FOUND:
1446
	case STATUS_NOT_A_DIRECTORY:
1447
	  retstat = -ENOTDIR;
1448
	  break;
1449
	case STATUS_FILE_IS_A_DIRECTORY:
1450
	  retstat = -EISDIR;
1451
	  break;
1452
	case STATUS_UNEXPECTED_IO_ERROR:
1453
	case STATUS_IO_PRIVILEGE_FAILED:
1454
	case STATUS_DEVICE_NOT_READY:
1455
	case STATUS_IO_DEVICE_ERROR:
1456
	case STATUS_OPEN_FAILED:
1457
	case STATUS_REPLY_MESSAGE_MISMATCH:
1458
	case STATUS_LOST_WRITEBEHIND_DATA:
1459
	  retstat = -EIO;
1460
	  break;
1461
	case STATUS_NOT_SUPPORTED:
1462
	case STATUS_ILLEGAL_FUNCTION:
1463
	case STATUS_WMI_NOT_SUPPORTED:
1464
	  retstat = -EOPNOTSUPP;
1465
	  break;
1466
	case STATUS_PIPE_DISCONNECTED:
1467
	case STATUS_CONNECTION_ABORTED:
1468
	case STATUS_CONNECTION_DISCONNECTED:
1469
	case STATUS_CONNECTION_RESET:
1470
	  retstat = -ECONNRESET;
1471
	  break;
1472
	default:
1473
	  break;
1474
  }
1475
1476
  return retstat;
1477
}
1478
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/chansrv/sound.c (-16 / +4919 lines)
 Lines 17-60    Link Here 
17
   Copyright (C) Jay Sorg 2009
17
   Copyright (C) Jay Sorg 2009
18
*/
18
*/
19
19
20
/* #define XRDP_ENABLE_ALSA	1	*/
21
#define XRDP_ENABLE_PULSEAUDIO	1
22
23
/* if XRDP_THREADED_PA_MAINLOOP is true, then PulseAudio is run using
24
 * the threaded mainloop model ;(e.g., "pa_threaded_mainloop_start()");
25
 * otherwise, it is run using the non-threaded mainloop model (e.g., 
26
 * by looping "pa_mainloop_iterate()").
27
 */
28
#define	XRDP_THREADED_PA_MAINLOOP	1
29
30
#include <stdio.h>
31
#include <fcntl.h>
32
#include <unistd.h>
33
#include <pwd.h>
34
#include <grp.h>
35
#include <string.h>
36
#include <X11/Xlib.h>
37
#if defined(__linux__)
38
#include <bits/local_lim.h>
39
#endif
40
#include <sys/timeb.h>
41
#include <dlfcn.h>
42
#include <time.h>
43
#include <glob.h>
44
#include <pwd.h>
45
#include <sys/types.h>
46
#include <sys/stat.h>
47
48
#include <pulse/pulseaudio.h>
49
#include <pulse/mainloop.h>
50
#include <pulse/thread-mainloop.h>
51
#include <pulse/gccmacro.h>
52
#include <pulse/def.h>
53
#include <pulse/version.h>
54
55
#include "defines.h"
20
#include "arch.h"
56
#include "arch.h"
21
#include "parse.h"
57
#include "parse.h"
22
#include "os_calls.h"
58
#include "os_calls.h"
59
#include "chansrv.h"
60
#include "devredir_defs.h"
61
#include "thread_calls.h"
62
#include "thread_macros.h"
63
#include "trans.h"
64
#include "sound_defs.h"
65
#ifdef XRDP_ENABLE_SOXCONVERT
66
#include "soxconvert.h"
67
#endif
68
#ifdef XRDP_ENABLE_ALSA
69
#include "alsa.h"
70
#endif
71
#include "dbg.h"
72
73
#undef MDBGLOG
74
#define MDBGLOG(...) (0)
75
76
#if defined(MAX_PDU_LENGTH)
77
#undef MAX_PDU_LENGTH
78
#endif
79
//#define		MAX_PDU_LENGTH		(MAX_STREAM)
80
#define		MAX_PDU_LENGTH		(MAX_STREAM / 2)
81
82
#if !defined(MINVAL)
83
#define MINVAL(x,y) (((x) > (y)) ? (y) : (x))
84
#endif
85
86
typedef struct {
87
	BYTE		bSize;
88
	WORD		wOutTime;
89
	WORD		wAckTime;
90
	WORD		wTrueOutTime;
91
	DWORD		dwLength;
92
} pktinfo;
93
94
typedef struct _pkt {
95
	struct _pkt *	next;
96
	struct _pkt *	prev;
97
	struct stream *	s[2];
98
	unsigned int	count;
99
	#define		PKT_MAGIC	0xfeefaaf0
100
	uint32_t	magic;
101
	unsigned int	byteCount;
102
	double		duration;
103
	BYTE		cBlockNo;
104
	tc_t		lock;
105
} pkt;
106
107
typedef struct _pktq {
108
	#define MAX_PKTQ	250
109
	#define SAFE_PKTQ_MIN	50
110
	#define SAFE_PKTQ_MAX	100
111
	pkt *			head;
112
	int			max;
113
	int			min;
114
	pkt *			items[MAX_PKTQ];
115
	unsigned int		top;
116
	unsigned int		bottom;
117
	unsigned int		count;
118
	int			(*enq)(struct _pktq *, struct _pkt *);
119
	pkt *			(*deq)(struct _pktq *);
120
	int			(*getCount)(struct _pktq *);
121
	int			(*getMax)(struct _pktq *);
122
	int			(*setMax)(struct _pktq *, int);
123
	int			(*getMin)(struct _pktq *);
124
	int			(*setMin)(struct _pktq *, int);
125
	unsigned int		(*ready)(struct _pktq *);
126
	void			(*__destructor)(struct _pktq *);
127
} pktq;
128
129
130
extern tc_t     g_mem_mutex;
131
extern tc_p     mutex_mem;
132
133
static unsigned char g_pktq_locked = 0;
134
static char g_pktq_holder[32] = "";
135
static unsigned char g_pktlog_locked = 0;
136
static char g_pktlog_holder[32] = "";
137
138
/* PulseAudio */
139
static unsigned char		raw = 1;
140
static pa_mainloop *		m = NULL;
141
static pa_threaded_mainloop *	mt = NULL;
142
static pa_context *		context = NULL;
143
static pa_stream *		stream = NULL;
144
static pa_mainloop_api *	mainloop_api = NULL;
145
static pa_io_event *		stdio_event = NULL;
146
static void *			buffer = NULL;
147
static size_t 			buffer_length = 0;
148
static size_t			buffer_index = 0;
149
static char *			stream_name = NULL;
150
static char *			client_name = NULL;
151
static char *			device = NULL;
152
static unsigned char		verbose = 0;
153
static pa_volume_t		volume = PA_VOLUME_NORM;
154
static unsigned char		volume_is_set = 0;
155
static enum {RECORD, PLAYBACK}	mode = RECORD;
156
static pa_channel_map channel_map;
157
static unsigned char		channel_map_set = 0;
158
static pa_stream_flags_t	flags = 0;
159
static size_t			latency = 0;
160
static size_t			process_time = 0;
161
162
#define SPEC_PCM	{ .format = PA_SAMPLE_S16LE,	.rate = 44100,	.channels = 2 };
163
#define	SPEC_ALAW	{ .format = PA_SAMPLE_ALAW,	.rate = 44100,	.channels = 2, }
164
#define	SPEC_ULAW	{ .format = PA_SAMPLE_ULAW,	.rate = 44100,	.channels = 2, }
165
#define	SPEC_IMA_ADPCM	SPEC_PCM
166
167
static pa_sample_spec		sample_spec = SPEC_ALAW;
168
//static pa_sample_spec		sample_spec = SPEC_PCM;
169
170
/* threads, mutexes, barriers, and condition variables */
171
static tc_t			g_cb_mutex;
172
static tc_p			mutex_cb = &g_cb_mutex;
173
174
static tc_t			g_init_mutex;
175
static tc_p			mutex_init = &g_init_mutex;
176
static tc_t			g_init_cond;
177
static tc_p			cond_init = (tc_p)NULL;
178
179
static tc_t			g_drain_mutex;
180
static tc_p			mutex_drain = &g_drain_mutex;
181
static tc_t			g_drain_cond;
182
static tc_p			cond_drain = (tc_p)(&g_drain_cond);
183
184
static tc_t			g_formats_barr;
185
static tc_p			barr_formats = &g_formats_barr;
186
187
static tc_t			g_event_mutex;
188
static tc_p			mutex_event = &g_event_mutex;
189
190
static tc_t			g_underrun_mutex;
191
static tc_p			mutex_underrun = &g_underrun_mutex;
192
193
static tc_t			g_stream_mutex;
194
static tc_p			mutex_stream = &g_stream_mutex;
195
196
static tc_t			g_pktq_thread;
197
static tc_p			thread_pktq = (tc_p)NULL;
198
static tc_t			g_thread_mutex;
199
static tc_p			mutex_thread = (tc_p)NULL;
200
201
static tc_t			g_ready_cond;
202
static tc_p			cond_ready = (tc_p)NULL;
203
static tc_t			g_ready_mutex;
204
static tc_p			mutex_ready = (tc_p)NULL;
205
206
static tc_t			g_stream_ready_cond;
207
static tc_p			cond_stream_ready = (tc_p)NULL;
208
static tc_t			g_stream_ready_mutex;
209
static tc_p			mutex_stream_ready = (tc_p)NULL;
210
211
static tc_t			g_rebuilding_cond;
212
static tc_p			cond_rebuilding = (tc_p)(&g_rebuilding_cond);
213
static tc_t			g_rebuilding_mutex;
214
static tc_p			mutex_rebuilding = (tc_p)(&g_rebuilding_mutex);
215
216
static tc_t			g_pause_cond;
217
static tc_p			cond_pause = (tc_p)NULL;
218
static tc_t			g_pause_mutex;
219
static tc_p			mutex_pause = (tc_p)NULL;
220
221
static tc_t			g_pause_ack_cond;
222
static tc_p			cond_pause_ack = (tc_p)NULL;
223
static tc_t			g_pause_ack_mutex;
224
static tc_p			mutex_pause_ack = (tc_p)NULL;
225
226
static tc_t			g_new_mutex;
227
static tc_p			mutex_new = (tc_p)NULL;
228
229
static tc_t			g_pa_cond;
230
static tc_p			cond_pa = (tc_p)NULL;
231
232
static tc_t			g_buffer_cond;
233
static tc_p			cond_buffer = (tc_p)NULL;
234
static tc_t			g_buffer_mutex;
235
static tc_p			mutex_buffer = (tc_p)NULL;
236
237
static tc_t			g_sink_mutex;
238
static tc_p			mutex_sink = (tc_p)(&g_sink_mutex);
239
static tc_t			g_sink_cond;
240
static tc_p			cond_sink = (tc_p)(&g_sink_cond);
241
242
static tc_t			g_pa_thread;
243
static tc_p			thread_pa = (tc_p)NULL;
244
static tc_t			g_pa_mutex;
245
static tc_p			mutex_pa = (tc_p)NULL;
246
247
extern tc_t			g_out_mutex;
248
extern tc_p			mutex_out;
249
static tc_t			g_sound_mutex;
250
static tc_p			mutex_sound = (tc_p)NULL;
251
static tc_t			g_ins_mutex;
252
static tc_p			mutex_ins = (tc_p)NULL;
253
static tc_t			g_pktq_mutex;
254
static tc_p			mutex_pktq = (tc_p)NULL;
255
static tc_t			g_audio_mutex;
256
static tc_p			mutex_audio = (tc_p)NULL;
257
258
static tc_t			g_up_mutex;
259
static tc_p			mutex_up = (tc_p)NULL;
260
static tc_t			g_close_mutex;
261
static tc_p			mutex_close = (tc_p)NULL;
262
static tc_t			g_close_rw;
263
static tc_p			rw_close = (tc_p)NULL;
264
static tc_t			g_pktlog_mutex;
265
static tc_p			mutex_pktlog = (tc_p)NULL;
266
static tc_t			g_pktready_mutex;
267
static tc_p			mutex_pktready = (tc_p)NULL;
268
static tc_t			g_train_mutex;
269
static tc_p			mutex_train = (tc_p)NULL;
270
static tc_t			g_send_mutex;
271
static tc_p			mutex_send = (tc_p)NULL;
272
static tc_t			g_socket_mutex;
273
static tc_p			mutex_socket = (tc_p)NULL;
274
static tc_t			g_prev_mutex;
275
static tc_p			mutex_prev = (tc_p)NULL;
276
static tc_t			g_formats_mutex;
277
static tc_p			mutex_formats = (tc_p)NULL;
278
static tc_t			g_block_mutex;
279
static tc_p			mutex_block = (tc_p)NULL;
280
281
static tc_t			mutex_attribute;
282
static tc_p			g_attr = (tc_p)NULL;
283
284
static char			g_hopper[MAX_STREAM];
285
static size_t			g_hopper_index = 0;
286
static size_t			g_hopper_length = 0;
287
288
#define	MAX_PKTLOG		2048
289
static char			selfpipe_path[512];
290
static pktinfo			pktlog[MAX_PKTLOG];
291
static unsigned int		g_is_child = 0;
292
static int			g_sink_index = -1;
293
static volatile unsigned char	g_sink_input_count = 0;
294
static volatile unsigned int	g_ready_waiting = 0;
295
static volatile unsigned int	g_ready_count = 0;
296
static volatile int		g_ready_playbytes = 0;
297
static volatile int		g_ready_playtime = 0;
298
//static unsigned int		g_preferred_wave_format = WAVE_FORMAT_PCM;
299
//static unsigned int		g_preferred_wave_format = WAVE_FORMAT_IMA_ADPCM;
300
static unsigned int		g_preferred_wave_format = WAVE_FORMAT_ALAW;
301
//static unsigned int		g_preferred_wave_format = WAVE_FORMAT_MULAW;
302
static volatile unsigned int	g_trained = 0;
303
static volatile unsigned int	g_received_close_pdu = 0;
304
static unsigned int		g_callee_frees = 1;
305
static volatile unsigned int	g_sound_up = 0;
306
static unsigned int		g_ready_triggered = 0;
307
static unsigned int		g_ready_triggered_count = 0;
308
static volatile int		g_client_format_index = -1;
309
static volatile WORD		g_client_format = 0x0000;
310
static int			g_client_format_count = 0;
311
static volatile unsigned int	g_sound_ready_to_train = 0;
312
static volatile unsigned int	g_sound_ready_to_send = 0;
313
static volatile unsigned char	g_drain = 0;
314
static unsigned int		g_current_block = 0x01;
315
static double			g_prev_rtime = 0.;
316
static double			g_prev_duration = 0.;
317
static double			g_diff = 0.;
318
static int			g_format_byte_rate = 0;
319
static volatile unsigned int	g_latency = 0;
320
321
322
//static unsigned int	g_target_latency = 800;			/* in milliseconds */
323
//static unsigned int	g_high_latency = 1200;			/* in milliseconds */
324
//static unsigned int	g_max_latency = 1600;			/* in milliseconds */
325
//static unsigned int	g_low_latency = 600;			/* in milliseconds */
326
//static unsigned int	g_lower_latency = 400;			/* in milliseconds */
327
//static unsigned int	g_min_latency = 300;			/* in milliseconds */
328
329
static unsigned int	g_target_latency = 500;			/* in milliseconds */
330
static unsigned int	g_high_latency = 700;			/* in milliseconds */
331
static unsigned int	g_max_latency = 800;			/* in milliseconds */
332
static unsigned int	g_low_latency = 330;			/* in milliseconds */
333
static unsigned int	g_lower_latency = 220;			/* in milliseconds */
334
static unsigned int	g_min_latency = 150;			/* in milliseconds */
335
336
static volatile unsigned int	g_underruns = 0;		/* buffer underrun counter */
337
static long int		g_most_recent_underrun_timestamp = 0;
338
static volatile unsigned char	g_initialized = 0;
339
static volatile unsigned char	g_stream_ready = 0;
340
static volatile unsigned char	g_pa_ready = 0;
341
static volatile int	g_outstanding = 0;
342
static volatile int	g_outstanding_playtime = 200;
343
static volatile int	g_outstanding_playbytes = 44100 / 5;
344
static volatile int	g_client_formats_received = 0;
345
static volatile int	g_idle = 0;
346
static unsigned char	g_pause = 0;
347
static unsigned char	g_paused = 0;
348
static unsigned char	g_pause_acked = 0;
349
static volatile unsigned char	g_sink_query_waiting = 0;
350
static unsigned char	g_enable_skew_compensation = 1;
351
static unsigned char	g_drop_silence = 1;
352
static volatile unsigned int	g_thunk = 0;
353
static volatile unsigned char	g_rebuilding = 0;
354
355
static tbus		g_sound_socket = -1;
356
static tbus		g_sound_wait_obj = -1;
357
static tbus		g_sound_selfpipe = -1;
358
static tbus		g_fd = 0;
359
360
static const unsigned int g_audio_socket_type = WO_FIFO;	/* 1: PF_INET/PF_INET6; 2: PF_UNIX; 3: FIFO (named pipe)	*/
361
362
static pktq * g_pktq = (pktq *)NULL;
363
static struct stream * g_ins = NULL;
364
static SERVER_AUDIO_VERSION_AND_FORMATS * server_formats = NULL;
365
static CLIENT_AUDIO_VERSION_AND_FORMATS * client_formats = NULL;
366
static struct trans * g_audio = (struct trans *)NULL;
367
368
static int APP_CC reset_pktq(pktq *);
369
370
int APP_CC		sound_deinit(void);
371
static char * APP_CC	get_audio_socket(const char *);
372
static size_t APP_CC	sound_queue_packet(void *, size_t);
373
static int APP_CC	sound_estimate_latency(void);
374
static void * APP_CC	sound_pktq_loop(void *);
375
static void * APP_CC	sound_pa_start(void *);
376
static void * APP_CC	sound_timer_loop(void *);
377
static int APP_CC	sound_get_pulseaudio_server(const char **);
378
379
static void APP_CC pa_exit_signal_callback(pa_mainloop_api *, pa_signal_event *, int, void *);
380
381
static void APP_CC start_drain_noquit(void);
382
383
static int APP_CC	q_enq(pktq *, pkt *);
384
static int APP_CC	q_enq_old3(pktq *, pkt *);
385
static pkt * APP_CC	q_deq(pktq *);
386
static pkt * APP_CC	q_deq_old3(pktq *);
387
static int APP_CC	q_getCount(pktq *);
388
static int APP_CC	q_getMax(pktq *);
389
static int APP_CC	q_setMax(pktq *, int);
390
static int APP_CC	q_getMin(pktq *);
391
static int APP_CC	q_setMin(pktq *, int);
392
static unsigned int APP_CC	q_ready(pktq *);
393
static void APP_CC	destroy_pktq(pktq *);
394
395
396
static void APP_CC do_stream_write(size_t);
397
static void APP_CC stdin_callback(pa_mainloop_api *, pa_io_event *, int, pa_io_event_flags_t, void *);
398
static void APP_CC stdout_callback(pa_mainloop_api *, pa_io_event *, int, pa_io_event_flags_t f, void *);
399
static void APP_CC stream_read_callback(pa_stream *, size_t, void *);
400
static void APP_CC stream_write_callback(pa_stream *, size_t, void *);
401
static void APP_CC stream_suspended_callback(pa_stream *, void *);
402
static void APP_CC stream_underflow_callback(pa_stream *, void *);
403
static void APP_CC stream_overflow_callback(pa_stream *, void *);
404
static void APP_CC stream_buffer_attr_callback(pa_stream *, void *);
405
static void APP_CC stream_event_callback(pa_stream *, const char *, pa_proplist *, void *);
406
static void APP_CC context_state_callback(pa_context *, void *);
407
static void APP_CC pa_quit(int);
408
409
static void APP_CC pa_subscribe_cb(struct pa_context *, enum pa_subscription_event_type, uint32_t, void *);
410
static void APP_CC pa_context_success_cb(pa_context *, int, void *);
411
static void APP_CC pa_stream_latency_update_cb(pa_stream *, void *);
412
static void APP_CC pa_sink_input_info_cb(pa_context *, const pa_sink_input_info *, int, void *);
413
414
extern int g_rdpsnd_chan_id;		/* in chansrv.c		*/
415
416
#if defined(XRDP_ENABLE_ALSA)
417
extern alsa * g_alsa;
418
#endif
23
419
24
extern int g_rdpsnd_chan_id; /* in chansrv.c */
25
420
26
/*****************************************************************************/
421
/*****************************************************************************/
27
int APP_CC
422
/* returns time in milliseconds
28
sound_init(void)
423
   this is like g_time2 in os_calls, but not milliseconds since machine was
424
   up, something else
425
   this is a time value similar to what the xserver uses */
426
static uint16_t APP_CC
427
sound_get_local_time(void)
29
{
428
{
429
  uint16_t rv = 0;
430
  //return g_time3();
431
  rv = (uint16_t)(((double)(g_time2()) / (double)(CLOCKS_PER_SEC)) * 1000);
432
  //MDBGLOG("sound","INFO\t[%s()]: done (rv = %d).",__func__,rv);
433
  return rv;
434
}
435
436
/*****************************************************************************/
437
static int APP_CC
438
sound_audioformat_from_name(WAVEFORMATEX ** ifmt, const char * FormatName) {
439
  size_t len = sizeof(WAVEFORMATEX);
440
  WAVEFORMATEX * afmt = (WAVEFORMATEX *)NULL;
441
  char tbuf[256];
442
  MPEGLAYER3WAVEFORMAT mp3;
443
  BYTE * b = (BYTE *)NULL;
444
  g_memset(&mp3, 0x00, sizeof(MPEGLAYER3WAVEFORMAT));
445
  if (ifmt != NULL) {
446
    afmt = *ifmt;
447
  }
448
  if (afmt == NULL) {
449
    afmt = (WAVEFORMATEX *)g_malloc(sizeof(WAVEFORMATEX) + ADPCM_WFX_EXTRA_BYTES + 4, 1);
450
  }
451
  if (afmt == NULL) {
452
    MDBGLOG("sound","ERROR\t[%s()]: afmt is NULL",__func__);
453
    return 1;
454
  }
455
  afmt->wFormatTag = XRDP_DEFAULT_WAVE_FORMAT;	/* default: PCM */
456
  afmt->nChannels = 0x0002;			/* default: 2 channels */
457
  afmt->nSamplesPerSec = 0x00005622;		/* default: 0x5622 = 22050 kHz */
458
  afmt->nAvgBytesPerSec = 0x00015888;		/* = nSamplesPerSec * nBlockAlign = 0x15888 = 88200 */
459
  afmt->nBlockAlign = 0x0004;			/* if wFormatTag is WAVE_FORMAT_PCM or WAVE_FORMAT_EXTENSIBLE, nBlockAlign must be equal to the product of nChannels and wBitsPerSample divided by 8 (bits per byte) */
460
  afmt->wBitsPerSample = 0x0010;		/* if wFormatTag is WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16 */
461
  afmt->cbSize = 0x0000;			/* size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure */
462
  //afmt->data = NULL;				/* no extra information for default (PCM) */
463
  if (FormatName == NULL || g_strlen(FormatName) == 0 || !g_strncmp(FormatName,"PCM",g_strlen(FormatName)) || !g_strncmp(FormatName,"pcm",g_strlen(FormatName))) {
464
    afmt->wFormatTag = WAVE_FORMAT_PCM;
465
  }
466
  else if (!g_strncmp(FormatName,"ADPCM",g_strlen(FormatName)) || !g_strncmp(FormatName,"adpcm",g_strlen(FormatName))) {
467
    afmt->wFormatTag = WAVE_FORMAT_ADPCM;
468
    afmt->nChannels = 0x0002;
469
    afmt->nSamplesPerSec = 0x00005622;		/* = 22050Hz */
470
    afmt->nAvgBytesPerSec = 0x00005727;		/* = 22311Hz */
471
    afmt->nBlockAlign = 0x0400;
472
    afmt->wBitsPerSample = 0x0004;
473
    afmt->cbSize = ADPCM_WFX_EXTRA_BYTES;
474
    //afmt->data = (BYTE *)g_malloc(sizeof(BYTE) * afmt->cbSize,1);
475
    afmt->data[0] = 0xf4;
476
    afmt->data[1] = 0x03;
477
    afmt->data[2] = 0x07;
478
    afmt->data[3] = 0x00;
479
    afmt->data[4] = 0x00;
480
    afmt->data[5] = 0x01;
481
    afmt->data[6] = 0x00;
482
    afmt->data[7] = 0x00;
483
    afmt->data[8] = 0x00;
484
    afmt->data[9] = 0x02;
485
    afmt->data[10] = 0x00;
486
    afmt->data[11] = 0xff;
487
    afmt->data[12] = 0x00;
488
    afmt->data[13] = 0x00;
489
    afmt->data[14] = 0x00;
490
    afmt->data[15] = 0x00;
491
    afmt->data[16] = 0xc0;
492
    afmt->data[17] = 0x00;
493
    afmt->data[18] = 0x40;
494
    afmt->data[19] = 0x00;
495
    afmt->data[20] = 0xf0;
496
    afmt->data[21] = 0x00;
497
    afmt->data[22] = 0x00;
498
    afmt->data[23] = 0x00;
499
    afmt->data[24] = 0xcc;
500
    afmt->data[25] = 0x01;
501
    afmt->data[26] = 0x30;
502
    afmt->data[27] = 0xff;
503
    afmt->data[28] = 0x88;
504
    afmt->data[29] = 0x01;
505
    afmt->data[30] = 0x18;
506
    afmt->data[31] = 0xff;
507
  }
508
  else if (!g_strncmp(FormatName,"IMA",g_strlen(FormatName)) || !g_strncmp(FormatName,"ima",g_strlen(FormatName)) || !g_strncmp(FormatName,"IMA_ADPCM",g_strlen(FormatName)) || !g_strncmp(FormatName,"IMA ADPCM",g_strlen(FormatName)) || !g_strncmp(FormatName,"ima_adpcm",g_strlen(FormatName)) || !g_strncmp(FormatName,"ima adpcm",g_strlen(FormatName))) {
509
    afmt->wFormatTag = WAVE_FORMAT_IMA_ADPCM;
510
    afmt->nChannels = 0x0002;
511
    afmt->nSamplesPerSec = 0x00005622;		/* = 22050Hz */
512
    afmt->nAvgBytesPerSec = 0x000056b9;		/* = 22201Hz */
513
    afmt->nBlockAlign = 0x0400;
514
    afmt->wBitsPerSample = 0x0004;
515
    afmt->cbSize = 0x0002;
516
    afmt->data[0] = 0xf9;
517
    afmt->data[1] = 0x03;
518
  }
519
  else if (!g_strncmp(FormatName,"MP3",g_strlen(FormatName)) || !g_strncmp(FormatName,"mp3",g_strlen(FormatName)) || !g_strncmp(FormatName,"MPEGLAYER3",g_strlen(FormatName))) {
520
    mp3.wID = MPEGLAYER3_ID_MPEG;
521
    mp3.fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
522
    //mp3.nBlockSize = MPEGLAYER3_NBLOCKSIZE;
523
    mp3.nBlockSize = 313;
524
    mp3.nFramesPerBlock = MPEGLAYER3_NFRAMESPERBLOCK;
525
    mp3.nCodecDelay = MPEGLAYER3_NCODECDELAY;
526
    afmt->wFormatTag = WAVE_FORMAT_MPEGLAYER3;
527
    afmt->nChannels = 0x0002;
528
    //afmt->nSamplesPerSec = 0x00005622;
529
    afmt->nSamplesPerSec = 44100;
530
    //afmt->nAvgBytesPerSec = 128 * (1024 / 8);
531
    afmt->nAvgBytesPerSec = 176400;
532
    //afmt->wBitsPerSample = 0x0000;
533
    afmt->wBitsPerSample = 16;
534
    afmt->nBlockAlign = 4;
535
    afmt->cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
536
    b = (BYTE *)(&mp3);
537
    afmt->data[0] = b[1];
538
    afmt->data[1] = b[0];
539
    afmt->data[2] = b[3];
540
    afmt->data[3] = b[2];
541
    afmt->data[4] = b[5];
542
    afmt->data[5] = b[4];
543
    afmt->data[6] = b[7];
544
    afmt->data[7] = b[6];
545
    afmt->data[8] = b[9];
546
    afmt->data[9] = b[8];
547
    afmt->data[10] = b[11];
548
    afmt->data[11] = b[10];
549
  }
550
  else if (!g_strncmp(FormatName,"ULAW",g_strlen(FormatName)) || !g_strncmp(FormatName,"ulaw",g_strlen(FormatName)) || !g_strncmp(FormatName,"MULAW",g_strlen(FormatName)) || !g_strncmp(FormatName,"mulaw",g_strlen(FormatName)) || !g_strncmp(FormatName,"AU",g_strlen(FormatName)) || !g_strncmp(FormatName,"au",g_strlen(FormatName))) {
551
    afmt->wFormatTag = WAVE_FORMAT_MULAW;
552
    afmt->nChannels = 0x0002;
553
    afmt->nSamplesPerSec = 0x00005622 * afmt->nChannels;	/* = 22050Hz * nChannels */
554
    afmt->nAvgBytesPerSec = 0x0000ac44 * afmt->nChannels;	/* = 22201Hz * nChannels */
555
    afmt->nBlockAlign = 0x0002;
556
    afmt->wBitsPerSample = 0x0008;
557
    afmt->cbSize = 0x0000;
558
  }
559
  else if (!g_strncmp(FormatName,"ALAW",g_strlen(FormatName)) || !g_strncmp(FormatName,"alaw",g_strlen(FormatName))) {
560
    afmt->wFormatTag = WAVE_FORMAT_ALAW;
561
    afmt->nChannels = 0x0002;
562
    afmt->nSamplesPerSec = 0x00005622 * afmt->nChannels;
563
    afmt->nAvgBytesPerSec = 0x0000ac44 * afmt->nChannels;
564
    afmt->nBlockAlign = 0x0002;
565
    afmt->wBitsPerSample = 0x0008;
566
    afmt->cbSize = 0x0000;
567
  }
568
  else if (!g_strncmp(FormatName,"MSG723",g_strlen("MSG723")) || !g_strncmp(FormatName,"msg723",g_strlen("msg723"))) {
569
    afmt->wFormatTag = WAVE_FORMAT_MSG723;
570
  }
571
  else if (!g_strncmp(FormatName,"GSM610",g_strlen(FormatName)) || !g_strncmp(FormatName,"gsm610",g_strlen(FormatName)) || !g_strncmp(FormatName,"GSM",g_strlen(FormatName)) || !g_strncmp(FormatName,"gsm",g_strlen(FormatName))) {
572
    afmt->wFormatTag = WAVE_FORMAT_GSM610;
573
    afmt->nChannels = 0x0001;
574
    afmt->nSamplesPerSec = 0x00005622;
575
    afmt->nAvgBytesPerSec = 0x0000117e;
576
    afmt->nBlockAlign = 0x0041;
577
    afmt->wBitsPerSample = 0x0000;
578
    afmt->cbSize = 0x0002;
579
    afmt->data[0] = 0x40;
580
    afmt->data[1] = 0x01;
581
  }
582
  else if (!g_strncmp(FormatName,"HIGSM610",g_strlen(FormatName)) || !g_strncmp(FormatName,"higsm610",g_strlen(FormatName)) || !g_strncmp(FormatName,"HIGSM",g_strlen(FormatName)) || !g_strncmp(FormatName,"higsm",g_strlen(FormatName))) {
583
    afmt->wFormatTag = WAVE_FORMAT_GSM610;
584
    afmt->nChannels = 0x0001;
585
    afmt->nSamplesPerSec = 0x0000ac44;
586
    afmt->nAvgBytesPerSec = 0x000022fd;
587
    afmt->nBlockAlign = 0x0041;
588
    afmt->wBitsPerSample = 0x0000;
589
    afmt->cbSize = 0x0002;
590
    afmt->data[0] = 0x40;
591
    afmt->data[1] = 0x01;
592
  }
593
  else if (!g_strncmp(FormatName,"HIPCM",g_strlen("HIPCM")) || !g_strncmp(FormatName,"hipcm",g_strlen("hipcm"))) {
594
    afmt->wFormatTag = WAVE_FORMAT_PCM;
595
    afmt->nChannels = 0x0002;
596
    afmt->nSamplesPerSec = 44100;
597
    afmt->nAvgBytesPerSec = 0x0002B110;
598
    afmt->nBlockAlign = 0x0004;
599
    afmt->wBitsPerSample = 0x0010;
600
    afmt->cbSize = 0x0000;
601
    //afmt->data = NULL;
602
  }
603
  else {
604
    afmt->wFormatTag = WAVE_FORMAT_UNKNOWN;
605
  }
606
  if (ifmt != NULL && afmt != NULL && afmt != *ifmt) {
607
    WAVEFORMATEX * ofmt = (WAVEFORMATEX *)NULL;
608
    len += afmt->cbSize;
609
    if (len > 0) {
610
      ofmt = (WAVEFORMATEX *)g_realloc(afmt, len + 4);
611
    }
612
    else {
613
      ofmt = afmt;
614
    }
615
    *ifmt = ofmt;
616
  }
30
  return 0;
617
  return 0;
31
}
618
}
32
619
33
/*****************************************************************************/
620
/*****************************************************************************/
34
int APP_CC
621
static int APP_CC
35
sound_deinit(void)
622
sound_AUDIO_FORMAT_out(struct stream* s, AUDIO_FORMAT *afmt) {
36
{
623
  int rv = 0;
624
625
  if (verbose) {
626
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
627
  }
628
629
  if (s == NULL || afmt == NULL) {
630
    rv = -1;
631
    goto end;
632
  }
633
634
  out_uint16_le(s, afmt->wFormatTag);
635
  out_uint16_le(s, afmt->nChannels);
636
  out_uint32_le(s, afmt->nSamplesPerSec);
637
  out_uint32_le(s, afmt->nAvgBytesPerSec);
638
  out_uint16_le(s, afmt->nBlockAlign);
639
  out_uint16_le(s, afmt->wBitsPerSample);
640
  out_uint16_le(s, afmt->cbSize);
641
  if (afmt->cbSize > 0) {
642
    out_uint8a(s, afmt->data, afmt->cbSize);
643
  }
644
645
 end:;
646
  return rv;
647
}
648
649
/*****************************************************************************/
650
static int APP_CC
651
sound_AUDIO_FORMAT_in(struct stream * s, AUDIO_FORMAT ** ifmt) {
652
  AUDIO_FORMAT * afmt = (AUDIO_FORMAT *)NULL;
653
  AUDIO_FORMAT * ofmt = (AUDIO_FORMAT *)NULL;
654
  size_t	len = 0;
655
  uint16_t	idx;
656
657
  if (verbose) {
658
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
659
  }
660
661
  if (ifmt == NULL) {
662
    MDBGLOG("sound","ERROR\t[%s()]: ifmt is NULL",__func__);
663
  }
664
  else {
665
    afmt = (AUDIO_FORMAT *)g_malloc((sizeof(AUDIO_FORMAT) + 32) + 4, 1);
666
    in_uint16_le(s, afmt->wFormatTag);
667
    in_uint16_le(s, afmt->nChannels);
668
    in_uint32_le(s, afmt->nSamplesPerSec);
669
    in_uint32_le(s, afmt->nAvgBytesPerSec);
670
    in_uint16_le(s, afmt->nBlockAlign);
671
    in_uint16_le(s, afmt->wBitsPerSample);
672
    in_uint16_le(s, afmt->cbSize);
673
    if (afmt->cbSize > 0) {
674
      in_uint8a(s, afmt->data, MIN(afmt->cbSize,32));
675
    }
676
    len = sizeof(AUDIO_FORMAT) + afmt->cbSize + 4;
677
    if (len > (sizeof(AUDIO_FORMAT) + 32)) {
678
      ofmt = (AUDIO_FORMAT *)g_realloc(afmt, len);
679
    }
680
    else {
681
      ofmt = afmt;
682
    }
683
    *ifmt = ofmt;
684
  }
685
37
  return 0;
686
  return 0;
38
}
687
}
39
688
40
/*****************************************************************************/
689
/*****************************************************************************/
41
int APP_CC
690
static int APP_CC
42
sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
691
sound_SNDPROLOG_in(struct stream* s, SNDPROLOG *hdr) {
43
              int total_length)
692
  if (verbose) {
44
{
693
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
694
  }
695
  in_uint8(s, hdr->msgType);
696
  in_uint8(s, hdr->bPad);
697
  in_uint16_le(s, hdr->BodySize);
45
  return 0;
698
  return 0;
46
}
699
}
47
700
48
/*****************************************************************************/
701
/*****************************************************************************/
49
int APP_CC
702
static int APP_CC
50
sound_get_wait_objs(tbus* objs, int* count, int* timeout)
703
sound_process_SNDC_QUALITYMODE(struct stream* s, SNDPROLOG *hdr, QUALITY_MODE *pdu) {
51
{
704
705
  if (verbose) {
706
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
707
  }
708
709
  if (g_callee_frees && pdu != NULL) {
710
    SOUND_FREE(pdu);
711
  }
712
52
  return 0;
713
  return 0;
53
}
714
}
54
715
55
/*****************************************************************************/
716
/*****************************************************************************/
56
int APP_CC
717
static int APP_CC
57
sound_check_wait_objs(void)
718
sound_process_SNDC_FORMATS(struct stream* s, SNDPROLOG *hdr, CLIENT_AUDIO_VERSION_AND_FORMATS * pdu) {
58
{
719
  int rv = 0;
720
  unsigned int idx = 0;
721
  unsigned int lmt = 0;
722
723
  if (verbose) {
724
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
725
  }
726
727
  if (pdu == NULL || s == NULL || hdr == NULL) {
728
    rv = -1;
729
    goto end;
730
  }
731
732
  pdu->Header.msgType = hdr->msgType;
733
  pdu->Header.bPad = hdr->bPad;
734
  pdu->Header.BodySize = hdr->BodySize;
735
  in_uint32_le(s, pdu->dwFlags);
736
  in_uint32_le(s, pdu->dwVolume);
737
  in_uint32_le(s, pdu->dwPitch);
738
  in_uint16_le(s, pdu->wDGramPort);
739
  in_uint16_le(s, pdu->wNumberOfFormats);
740
  in_uint8(s, pdu->cLastBlockConfirmed);
741
  in_uint16_le(s, pdu->wVersion);
742
  in_uint8(s, pdu->bPad);
743
744
  lmt = pdu->wNumberOfFormats;
745
  pdu->sndFormats = (AUDIO_FORMAT **)g_malloc(sizeof(AUDIO_FORMAT *) * lmt, 1);
746
  for (idx = 0; idx < lmt; idx++) {
747
    sound_AUDIO_FORMAT_in(s, &(pdu->sndFormats[idx]));
748
  }
749
750
 end:;
751
  if (g_callee_frees && pdu != NULL) {
752
    SOUND_FREE(pdu);
753
  }
754
  return rv;
755
}
756
757
/*****************************************************************************/
758
static int APP_CC
759
sound_process_SNDC_CLOSE(struct stream* s, SNDPROLOG *hdr) {
760
  int rv = 0;
761
762
  if (verbose) {
763
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
764
  }
765
766
  TC_MUTEX_LOCK(mutex_close);
767
  g_received_close_pdu = 1;
768
  TC_MUTEX_UNLOCK(mutex_close);
769
  TC_MUTEX_LOCK(mutex_sound);
770
  TC_MUTEX_LOCK(mutex_ready);
771
  if (g_ready_waiting > 0) {
772
    if (g_ready_waiting > 1) {
773
      TC_COND_BROADCAST(cond_ready);
774
    }
775
    else {
776
      TC_COND_SIGNAL(cond_ready);
777
    }
778
  }
779
  TC_MUTEX_UNLOCK(mutex_ready);
780
  TC_MUTEX_LOCK(mutex_pa);
781
  TC_COND_BROADCAST(cond_pa);
782
  TC_MUTEX_UNLOCK(mutex_pa);
783
  sound_deinit();
784
  TC_MUTEX_UNLOCK(mutex_sound);
785
786
 end:;
787
  return rv;
788
}
789
790
/*****************************************************************************/
791
static int APP_CC
792
sound_process_SNDC_WAVECONFIRM(struct stream * s, SNDPROLOG * hdr, SNDWAV_CONFIRM * pdu) {
793
  int rv = 0;
794
  int dwlen = 0;
795
  uint32_t lat = 0;
796
  pktinfo tinfo;
797
798
  if (verbose) {
799
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
800
  }
801
802
  g_memset(&tinfo,0,sizeof(pktinfo));
803
804
  if (s == NULL || pdu == NULL) {
805
    MDBGLOG("sound","ERROR\t[%s()]: NULL pointer (s = %p, pdu = %p)",__func__,s,pdu);
806
    rv = -1;
807
    goto end;
808
  }
809
810
  in_uint16_le(s, pdu->wTimeStamp);
811
  in_uint8(s, pdu->cConfirmedBlockNo);
812
  in_uint8(s, pdu->bPad);
813
814
  {
815
    MB;
816
    TC_MUTEX_LOCK(mutex_pktlog);
817
    if (pdu->cConfirmedBlockNo < MAX_PKTLOG && pktlog[(pdu->cConfirmedBlockNo)].wOutTime > 0) {
818
      pktlog[(pdu->cConfirmedBlockNo)].wAckTime = pdu->wTimeStamp;
819
      lat = g_latency = (pktlog[(pdu->cConfirmedBlockNo)].wAckTime > pktlog[(pdu->cConfirmedBlockNo)].wOutTime) ? pktlog[(pdu->cConfirmedBlockNo)].wAckTime - pktlog[(pdu->cConfirmedBlockNo)].wOutTime : (65536 - pktlog[(pdu->cConfirmedBlockNo)].wOutTime) + pktlog[(pdu->cConfirmedBlockNo)].wAckTime;
820
      if (g_outstanding > 0) {
821
	g_outstanding--;
822
      }
823
      else {
824
	g_thunk++;
825
      }
826
      g_outstanding_playbytes -= pktlog[(pdu->cConfirmedBlockNo)].dwLength;
827
      g_outstanding_playtime = (g_outstanding_playbytes > 0) ? pa_bytes_to_usec(g_outstanding_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
828
      g_outstanding_playtime *= 1;
829
      g_memcpy(&tinfo,&(pktlog[(pdu->cConfirmedBlockNo)]),sizeof(pktinfo));
830
      g_memset(&(pktlog[(pdu->cConfirmedBlockNo)]),0,sizeof(pktinfo));
831
    }
832
    TC_MUTEX_LOCK(mutex_ready);
833
    if (g_ready_playtime > g_high_latency) {
834
      TC_MUTEX_UNLOCK(mutex_ready);
835
      TC_MUTEX_LOCK(mutex_pktq);
836
      if (g_pktq != NULL && g_pktq->count > 0) {
837
	reset_pktq(g_pktq);
838
      }
839
      TC_MUTEX_UNLOCK(mutex_pktq);
840
    }
841
    else {
842
      TC_MUTEX_UNLOCK(mutex_ready);
843
    }
844
    TC_MUTEX_UNLOCK(mutex_pktlog);
845
  }
846
847
 end:;
848
  if (1 || (verbose && pdu != NULL)) {
849
    MDBGLOG("sound","INFO\t[%s()]:   <<>> ",__func__);
850
    MDBGLOG("sound","\t*\tg_outstanding = %d; g_ready_count = %d; g_latency = %d",g_outstanding,g_ready_count,lat);
851
    MDBGLOG("sound","\t*\tcConfirmedBlockNo = %d; wTimeStamp (wAckTime) = %d",pdu->cConfirmedBlockNo,pdu->wTimeStamp);
852
    MDBGLOG("sound","\t*\tpktlog->wOutTime = %d; pktlog->wTrueOutTime = %d; pktlog->dwLength = %d",tinfo.wOutTime,tinfo.wTrueOutTime,tinfo.dwLength);
853
    MDBGLOG("sound","\t*\tg_outstanding_playbytes = %d; g_outstanding_playtime = %d\n",g_outstanding_playbytes,g_outstanding_playtime);
854
  }
855
  if (g_callee_frees && pdu != NULL) {
856
    if (pdu->__destructor != NULL) {
857
      pdu->__destructor(pdu);
858
    }
859
    else {
860
      g_free(pdu);
861
    }
862
    pdu = NULL;
863
  }
864
  return rv;
865
}
866
867
/*****************************************************************************/
868
static int APP_CC
869
sound_process_SNDC_TRAININGCONFIRM(struct stream * s, SNDPROLOG * hdr, SNDTRAININGCONFIRM * pdu) {
870
  int rv = 0;
871
872
  if (verbose) {
873
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
874
  }
875
876
  if (pdu == NULL || s == NULL || hdr == NULL) {
877
    rv = -1;
878
    goto end;
879
  }
880
881
  pdu->Header.msgType = hdr->msgType;
882
  pdu->Header.bPad = hdr->bPad;
883
  pdu->Header.BodySize = hdr->BodySize;
884
885
  in_uint16_le(s, pdu->wTimeStamp);
886
  in_uint16_le(s, pdu->wPackSize);
887
888
 end:;
889
  if (g_callee_frees && pdu != NULL) {
890
    SOUND_FREE(pdu);
891
  }
892
  return rv;
893
}
894
895
/*****************************************************************************/
896
static void APP_CC
897
destroy_SNDWAV(void *pdu) {
898
  if (verbose) {
899
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
900
  }
901
  if (pdu != NULL) {
902
    if (((SNDWAV *)pdu)->Data != NULL) {
903
      g_free(((SNDWAV *)pdu)->Data);
904
    }
905
    g_free((SNDWAV *)pdu);
906
  }
907
}
908
909
/*****************************************************************************/
910
static void APP_CC
911
destroy_SNDCLOSE(void *pdu) {
912
  if (verbose) {
913
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
914
  }
915
  //g_free((SNDCLOSE *)pdu);
916
}
917
918
/*****************************************************************************/
919
static void APP_CC
920
destroy_AUDIO_FORMAT(void *pdu) {
921
  if (verbose) {
922
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
923
  }
924
  //g_free(((AUDIO_FORMAT *)pdu)->data);
925
  //g_free((AUDIO_FORMAT *)pdu);
926
}
927
928
/*****************************************************************************/
929
static void APP_CC
930
destroy_SNDWAVINFO(void *pdu) {
931
  if (verbose) {
932
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
933
  }
934
  if ((((SNDWAVINFO *)pdu)->appendix != NULL) && (((SNDWAVINFO *)pdu)->alen > 0)) {
935
    if ( ((SNDWAV *)(((SNDWAVINFO *)pdu)->appendix))->__destructor != NULL ) {
936
      (*((SNDWAV *)(((SNDWAVINFO *)pdu)->appendix))->__destructor)((void *)((SNDWAVINFO *)pdu)->appendix);
937
    }
938
    g_free((SNDWAVINFO *)pdu);
939
  }
940
}
941
942
/*****************************************************************************/
943
static void APP_CC
944
destroy_SNDWAV_CONFIRM(void *pdu) {
945
  if (verbose) {
946
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
947
  }
948
  if (pdu != NULL) {
949
    g_free((SNDWAV_CONFIRM *)pdu);
950
  }
951
}
952
953
/*****************************************************************************/
954
static void APP_CC
955
destroy_SNDTRAINING(void *pdu) {
956
  if (verbose) {
957
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
958
  }
959
  if (pdu != NULL) {
960
    if (((SNDTRAINING *)pdu)->data != NULL) {
961
      g_free(((SNDTRAINING *)pdu)->data);
962
      ((SNDTRAINING *)pdu)->data = NULL;
963
    }
964
    g_free((SNDTRAINING *)pdu);
965
  }
966
}
967
968
/*****************************************************************************/
969
static void APP_CC
970
destroy_SNDTRAININGCONFIRM(void *pdu) {
971
  if (verbose) {
972
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
973
  }
974
  if (pdu != NULL) {
975
    g_free((SNDTRAININGCONFIRM *)pdu);
976
  }
977
}
978
979
/*****************************************************************************/
980
static void APP_CC
981
destroy_CLIENT_AUDIO_VERSION_AND_FORMATS(void *pdu) {
982
  unsigned int idx = 0;
983
  unsigned int lmt = 0;
984
  CLIENT_AUDIO_VERSION_AND_FORMATS *tmp = NULL;
985
  AUDIO_FORMAT *cval = NULL;
986
987
  tmp = (CLIENT_AUDIO_VERSION_AND_FORMATS *)pdu;
988
  if (tmp != NULL) {
989
    lmt = tmp->wNumberOfFormats;
990
    if (tmp->sndFormats != NULL) {
991
      /*
992
      for (idx = 0; idx < lmt; idx++) {
993
	cval = (AUDIO_FORMAT *)tmp->sndFormats[idx];
994
	if (cval != NULL) {
995
	  if ( (*cval->__destructor) != NULL ) {
996
	    (*cval->__destructor)((void *)cval);
997
	  }
998
	}
999
      }
1000
      */
1001
    }
1002
    //g_free(tmp);
1003
  }
1004
}
1005
1006
/*****************************************************************************/
1007
static void APP_CC
1008
destroy_SERVER_AUDIO_VERSION_AND_FORMATS(void *pdu) {
1009
  if (pdu != NULL) {
1010
    destroy_CLIENT_AUDIO_VERSION_AND_FORMATS(pdu);
1011
  }
1012
}
1013
1014
/*****************************************************************************/
1015
static void APP_CC
1016
destroy_QUALITY_MODE(void *pdu) {
1017
  if (verbose) {
1018
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1019
  }
1020
  if (pdu != NULL) {
1021
    g_free((QUALITY_MODE *)pdu);
1022
  }
1023
}
1024
1025
/*****************************************************************************/
1026
static int APP_CC
1027
construct_AUDIO_FORMAT(AUDIO_FORMAT * pdu) {
1028
  pdu->__destructor = &destroy_AUDIO_FORMAT;
1029
  return 0;
1030
}
1031
1032
static AUDIO_FORMAT * APP_CC
1033
create_AUDIO_FORMAT() {
1034
  AUDIO_FORMAT *pdu = NULL;
1035
  pdu = (AUDIO_FORMAT *)g_malloc(sizeof(AUDIO_FORMAT),1);
1036
  pdu->__destructor = &destroy_AUDIO_FORMAT;
1037
  return pdu;
1038
}
1039
1040
1041
/*****************************************************************************/
1042
static int APP_CC
1043
construct_pktq(pktq * self) {
1044
  int rv = 0;
1045
  if (self == NULL) {
1046
    rv = -1;
1047
    goto end;
1048
  }
1049
  self->enq = &q_enq;
1050
  self->deq = &q_deq;
1051
  self->getCount = &q_getCount;
1052
  self->getMax = &q_getMax;
1053
  self->setMax = &q_setMax;
1054
  self->getMin = &q_getMin;
1055
  self->setMin = &q_setMin;
1056
  self->ready = &q_ready;
1057
  self->__destructor = &destroy_pktq;
1058
  self->setMax(self,SAFE_PKTQ_MAX);
1059
  self->setMin(self,SAFE_PKTQ_MIN);
1060
  g_memset(self->items,0,(MAX_PKTQ * sizeof(size_t)));
1061
  self->top = 0;
1062
  self->bottom = 0;
1063
  self->head = NULL;
1064
  self->count = 0;
1065
  TC_MUTEX_LOCK(mutex_ready);
1066
  g_ready_count = 0;
1067
  g_ready_playbytes = 0;
1068
  g_ready_playtime = 0;
1069
  TC_MUTEX_UNLOCK(mutex_ready);
1070
  /*
1071
  TC_MUTEX_LOCK(mutex_pktlog);
1072
  g_outstanding = 0;
1073
  g_outstanding_playbytes = 0;
1074
  g_outstanding_playtime = 0;
1075
  TC_MUTEX_UNLOCK(mutex_pktlog);
1076
  */
1077
 end:;
1078
  return rv;
1079
}
1080
1081
/*****************************************************************************/
1082
static int APP_CC
1083
reset_pktq(pktq * self) {
1084
  int rv = 0;
1085
  if (self == NULL) {
1086
    rv = -1;
1087
    goto end;
1088
  }
1089
  self->enq = &q_enq;
1090
  self->deq = &q_deq;
1091
  self->getCount = &q_getCount;
1092
  self->getMax = &q_getMax;
1093
  self->setMax = &q_setMax;
1094
  self->getMin = &q_getMin;
1095
  self->setMin = &q_setMin;
1096
  self->ready = &q_ready;
1097
  self->__destructor = &destroy_pktq;
1098
  if (self->count > 0 && self->deq != NULL) {
1099
    pkt * packet = (pkt *)NULL;
1100
    unsigned int idx = 0;
1101
    for (idx = 0; idx < self->count; idx++) {
1102
      packet = self->deq(self);
1103
      if (packet != NULL) {
1104
	//TC_MUTEX_LOCK(&(packet->lock));
1105
	if (packet->s[0] != NULL) {
1106
	  free_stream(packet->s[0]);
1107
	}
1108
	if (packet->s[1] != NULL) {
1109
	  free_stream(packet->s[1]);
1110
	}
1111
	packet->s[0] = NULL;
1112
	packet->s[1] = NULL;
1113
	//TC_MUTEX_UNLOCK(&(packet->lock));
1114
	g_free(packet);
1115
	packet = NULL;
1116
      }
1117
    }
1118
  }
1119
  self->setMax(self,SAFE_PKTQ_MAX);
1120
  self->setMin(self,SAFE_PKTQ_MIN);
1121
  g_memset(self->items,0,(MAX_PKTQ * sizeof(size_t)));
1122
  self->top = 0;
1123
  self->bottom = 0;
1124
  self->head = NULL;
1125
  self->count = 0;
1126
  TC_MUTEX_LOCK(mutex_ready);
1127
  g_ready_count = 0;
1128
  g_ready_playbytes = 0;
1129
  g_ready_playtime = 0;
1130
  TC_MUTEX_UNLOCK(mutex_ready);
1131
 end:;
1132
  return rv;
1133
}
1134
1135
/*****************************************************************************/
1136
static int APP_CC
1137
construct_SNDWAV_CONFIRM(SNDWAV_CONFIRM *pdu) {
1138
1139
  if (verbose) {
1140
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1141
  }
1142
1143
  pdu->__destructor = &destroy_SNDWAV_CONFIRM;
1144
1145
  return 0;
1146
}
1147
1148
/*****************************************************************************/
1149
static int APP_CC
1150
construct_SNDTRAININGCONFIRM(SNDTRAININGCONFIRM *pdu) {
1151
1152
  if (verbose) {
1153
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1154
  }
1155
1156
  pdu->__destructor = &destroy_SNDTRAININGCONFIRM;
1157
1158
  return 0;
1159
}
1160
1161
/*****************************************************************************/
1162
static int APP_CC
1163
construct_QUALITY_MODE(QUALITY_MODE *pdu) {
1164
1165
  if (verbose) {
1166
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1167
  }
1168
1169
  pdu->__destructor = &destroy_QUALITY_MODE;
1170
1171
  return 0;
1172
}
1173
1174
/*****************************************************************************/
1175
static int APP_CC
1176
construct_SNDCLOSE(SNDCLOSE *pdu) {
1177
1178
  if (verbose) {
1179
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1180
  }
1181
1182
  pdu->__destructor = &destroy_SNDCLOSE;
1183
  pdu->Header.msgType = SNDC_CLOSE;
1184
  pdu->Header.bPad = 0x00;		/* is this a magic number? although the MSDN docs indicate the value of this field is ignored, I used the value set forth in the MSDN example to be safe */
1185
  pdu->Header.BodySize = 0;		/* the total size in bytes for a basic PDU of this type is 16; however, the Header (which is 4 bytes in length) is not counted when calculating BodySize, so therefore the value of this field is initially set to 12 */
1186
1187
  return 0;
1188
}
1189
1190
/*****************************************************************************/
1191
static int APP_CC
1192
construct_SNDTRAINING(SNDTRAINING *pdu) {
1193
1194
  if (verbose) {
1195
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1196
  }
1197
1198
  pdu->__destructor = &destroy_SNDTRAINING;
1199
  pdu->Header.msgType = SNDC_TRAINING;
1200
  pdu->Header.bPad = 0x00;		/* is this a magic number? although the MSDN docs indicate the value of this field is ignored, I used the value set forth in the MSDN example to be safe */
1201
  pdu->Header.BodySize = 4;		/* the total size in bytes for a basic PDU of this type is 16; however, the Header (which is 4 bytes in length) is not counted when calculating BodySize, so therefore the value of this field is initially set to 12 */
1202
1203
  pdu->wTimeStamp = sound_get_local_time();
1204
  pdu->wPackSize = 0x0000;
1205
  pdu->data = NULL;
1206
1207
  return 0;
1208
}
1209
1210
/*****************************************************************************/
1211
static int APP_CC
1212
construct_SNDWAV(SNDWAV * pdu, unsigned int byteCount, BYTE * inData) {
1213
  int rv = 0;
1214
  uint32_t * pnum = (uint32_t *)NULL;
1215
1216
  if (pdu == NULL || byteCount < 1 || inData == NULL) {
1217
    rv = -1;
1218
    goto end;
1219
  }
1220
1221
  pnum = (uint32_t *)inData;
1222
  pdu->__destructor = &destroy_SNDWAV;
1223
  pdu->bPad = 0x00000000;
1224
  pdu->Data = inData;
1225
1226
 end:;
1227
  return rv;
1228
}
1229
1230
/*****************************************************************************/
1231
static int APP_CC
1232
construct_SNDWAVINFO(SNDWAVINFO * pdu, unsigned int sndFormatIndex, size_t byteCount, BYTE * inData) {
1233
  int rv = 0;
1234
  int idx = 0;
1235
  unsigned int lmt = 0;
1236
  DWORD tmp = 0x00000000;
1237
  DWORD b[4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
1238
  SNDWAV * wav = (SNDWAV *)NULL;
1239
1240
  if (verbose) {
1241
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1242
  }
1243
1244
  if (pdu == NULL || (byteCount > 0 && inData == NULL)) {
1245
    rv = -1;
1246
    goto end;
1247
  }
1248
1249
  pdu->__destructor = &destroy_SNDWAVINFO;
1250
  if (byteCount > 3) {
1251
    b[0] = inData[0];
1252
    b[1] = inData[1];
1253
    b[2] = inData[2];
1254
    b[3] = inData[3];
1255
1256
    tmp = (b[0] & 0x000000ff) | ((b[1] & 0x000000ff) << 8) | ((b[2] & 0x000000ff) << 16) | ((b[3] & 0x000000ff) << 24);
1257
  }
1258
  else if (byteCount > 2) {
1259
    b[0] = inData[0];
1260
    b[1] = inData[1];
1261
    b[2] = inData[2];
1262
    tmp = (b[0] & 0x000000ff) | ((b[1] & 0x000000ff) << 8) | ((b[2] & 0x000000ff) << 16);
1263
  }
1264
  else if (byteCount > 1) {
1265
    b[0] = inData[0];
1266
    b[1] = inData[1];
1267
    tmp = (b[0] & 0x000000ff) | ((b[1] & 0x000000ff) << 8);
1268
  }
1269
  else if (byteCount == 1) {
1270
    b[0] = inData[0];
1271
    tmp = (b[0] & 0x000000ff);
1272
  }
1273
1274
  pdu->Header.msgType = SNDC_WAVE;
1275
  pdu->Header.bPad = 0x7e;		/* is this a magic number? although the MSDN docs indicate the value of this field is ignored, I used the value set forth in the MSDN example to be safe */
1276
  pdu->Header.BodySize = 8 + MAX(byteCount, 4);
1277
  pdu->wTimeStamp = sound_get_local_time();
1278
  pdu->wFormatNo = sndFormatIndex;
1279
  pdu->bPad[0] = 0x00;
1280
  pdu->bPad[1] = 0x00;
1281
  pdu->bPad[2] = 0x00;
1282
  pdu->Data = tmp;
1283
  pdu->alen = (byteCount > 3) ? (byteCount - 4) : 0;
1284
  pdu->appendix = NULL;
1285
1286
  if (byteCount > 4) {
1287
    pdu->appendix = SOUND_NEW(SNDWAV);
1288
    construct_SNDWAV(pdu->appendix, (byteCount - 4), (inData + 4));
1289
  }
1290
1291
 end:;
1292
  return rv;
1293
}
1294
1295
1296
/*****************************************************************************/
1297
static int APP_CC
1298
sound_SNDCLOSE_out(struct stream* s, SNDCLOSE *pdu) {
1299
1300
  if (verbose) {
1301
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1302
  }
1303
1304
    /* Header [RDPSND PDU Header] */
1305
  out_uint8(s, pdu->Header.msgType);
1306
  out_uint8(s, pdu->Header.bPad);
1307
  out_uint16_le(s, pdu->Header.BodySize);
1308
1309
  return 0;
1310
}
1311
1312
/*****************************************************************************/
1313
static int APP_CC
1314
sound_SNDTRAINING_out(struct stream* s, SNDTRAINING *pdu) {
1315
  unsigned int idx = 0;
1316
1317
  if (verbose) {
1318
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1319
  }
1320
1321
    /* Header [RDPSND PDU Header] */
1322
  out_uint8(s, pdu->Header.msgType);
1323
  out_uint8(s, pdu->Header.bPad);
1324
  out_uint16_le(s, pdu->Header.BodySize);
1325
1326
  out_uint16_le(s, pdu->wTimeStamp);
1327
  out_uint16_le(s, pdu->wPackSize);
1328
1329
  if ((pdu->data != NULL) && (pdu->wPackSize > 0)) {
1330
    out_uint8a(s, pdu->data, pdu->wPackSize);
1331
  }
1332
1333
  return 0;
1334
}
1335
1336
/*****************************************************************************/
1337
static int APP_CC
1338
sound_SNDWAV_out(struct stream* s, SNDWAV *pdu, unsigned int byteCount) {
1339
  unsigned int idx = 0;
1340
  int lmt = 0;
1341
  int remain = 0;
1342
  int res = 0;
1343
  int tmp = 0;
1344
  char tbuf[256];
1345
1346
  if (s==NULL || pdu == NULL || (byteCount > 0 && pdu->Data == NULL) || s->p == NULL || s->data == NULL || s->size < 1) {
1347
    MDBGLOG("sound","ERROR\t[%s()]: s = %p, pdu = %p, byteCount = %d",__func__,s,pdu,byteCount);
1348
    res = -1;
1349
    goto end;
1350
  }
1351
1352
  out_uint32_le(s, pdu->bPad);
1353
1354
  tmp = s->p - s->data;
1355
  remain = s->size - tmp;
1356
  lmt = byteCount;
1357
  if (byteCount > remain) {
1358
    lmt = remain;
1359
  }
1360
  if (lmt > 0) {
1361
    if (verbose) {
1362
      MDBGLOG("sound","DEBUG\t[%s()]: lmt = %d",__func__,lmt);
1363
    }
1364
    out_uint8a(s, pdu->Data, lmt);
1365
    res = lmt;
1366
  }
1367
  else {
1368
    MDBGLOG("sound","ERROR\t[%s()]: !!! ERROR (stream buffer overrun) !!!",__func__);
1369
    res = -1;
1370
  }
1371
 end:;
1372
  return res;
1373
}
1374
1375
/*****************************************************************************/
1376
static int APP_CC
1377
sound_SNDWAVINFO_out(struct stream* s, SNDWAVINFO *pdu) {
1378
1379
    /* Header [RDPSND PDU Header] */
1380
  out_uint8(s, pdu->Header.msgType);
1381
  out_uint8(s, pdu->Header.bPad);
1382
  out_uint16_le(s, pdu->Header.BodySize);
1383
1384
  out_uint16_le(s, pdu->wTimeStamp);
1385
  out_uint16_le(s, pdu->wFormatNo);
1386
  out_uint8(s, pdu->cBlockNo);
1387
  out_uint8(s, pdu->bPad[0]);
1388
  out_uint8(s, pdu->bPad[1]);
1389
  out_uint8(s, pdu->bPad[2]);
1390
  out_uint32_le(s, pdu->Data);
1391
1392
  return 0;
1393
}
1394
1395
/*****************************************************************************/
1396
static int APP_CC
1397
construct_CLIENT_AUDIO_VERSION_AND_FORMATS(CLIENT_AUDIO_VERSION_AND_FORMATS * pdu) {
1398
  unsigned int idx = 0;
1399
  unsigned int lmt = 0;
1400
  AUDIO_FORMAT * tmp = (AUDIO_FORMAT *)NULL;
1401
1402
  if (verbose) {
1403
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1404
  }
1405
1406
  if (pdu == NULL) {
1407
    MDBGLOG("sound","ERROR\t[%s()]: pdu is NULL",__func__);
1408
  }
1409
  else {
1410
    pdu->__destructor = &destroy_CLIENT_AUDIO_VERSION_AND_FORMATS;
1411
    lmt = pdu->wNumberOfFormats;
1412
    for (idx=0;idx<lmt;idx++) {
1413
      tmp = pdu->sndFormats[idx];
1414
      construct_AUDIO_FORMAT(tmp);
1415
    }
1416
  }
1417
59
  return 0;
1418
  return 0;
60
}
1419
}
1420
1421
/*****************************************************************************/
1422
static int APP_CC
1423
construct_SERVER_AUDIO_VERSION_AND_FORMATS(SERVER_AUDIO_VERSION_AND_FORMATS * pdu, char ** fmts, unsigned int fmtc) {
1424
  int rv = 0;
1425
  int idx = 0;
1426
  unsigned int lmt = 0;
1427
1428
  if (verbose) {
1429
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1430
  }
1431
1432
  if (pdu == NULL || (fmtc > 0 && fmts == NULL)) {
1433
    MDBGLOG("sound","ERROR\t[%s()]: pdu = %p, fmtc = %d, fmts = %p",__func__, pdu, fmtc, fmts);
1434
    rv = -1;
1435
    goto end;
1436
  }
1437
1438
  g_memset(&(pdu->lock),0,sizeof(tc_t));
1439
  {
1440
    tc_t attr;
1441
    tc_p pattr = &attr;
1442
    TC_MUTATTR_INIT(pattr);
1443
    TC_MUTATTR_SETTYPE(pattr, TC_MUTEX_ERRORCHECK);
1444
    TC_MUTEX_INIT(&(pdu->lock), pattr);
1445
  }
1446
  TC_MUTEX_LOCK(&(pdu->lock));
1447
  pdu->__destructor = &destroy_SERVER_AUDIO_VERSION_AND_FORMATS;
1448
  pdu->Header.msgType = SNDC_FORMATS;
1449
  pdu->Header.bPad = 0x2b;		/* is this a magic number? although the MSDN docs indicate the value of this field is ignored, I used the value set forth in the MSDN example to be safe */
1450
  pdu->Header.BodySize = 20;		/* the total size in bytes for a basic PDU of this type is 24; however, the Header (which is 4 bytes in length) is not counted when calculating BodySize, so therefore the value of this field is initially set to 20 */
1451
  pdu->dwFlags = 0x0000;
1452
  pdu->dwVolume = 0x0000;
1453
  pdu->dwPitch = 0x0000;
1454
  pdu->wDGramPort = 0x0000;
1455
  pdu->wNumberOfFormats = fmtc;
1456
  pdu->cLastBlockConfirmed = 0xff;
1457
  pdu->wVersion = 0x05;
1458
  pdu->bPad = 0x00;
1459
  lmt = pdu->wNumberOfFormats;
1460
  pdu->sndFormats = g_malloc(sizeof(size_t),lmt);
1461
  if (lmt>0) {
1462
    for (idx = 0; idx < lmt ; idx++) {
1463
      AUDIO_FORMAT * tmp = (AUDIO_FORMAT *)NULL;
1464
      sound_audioformat_from_name(&tmp, fmts[idx]);
1465
      pdu->sndFormats[idx] = tmp;
1466
      pdu->Header.BodySize = pdu->Header.BodySize + 18;
1467
      if (pdu->sndFormats[idx]->cbSize > 0) {
1468
        pdu->Header.BodySize = pdu->Header.BodySize + pdu->sndFormats[idx]->cbSize;
1469
      }
1470
      construct_AUDIO_FORMAT((AUDIO_FORMAT *)(pdu->sndFormats[idx]));
1471
    }
1472
  }
1473
  TC_MUTEX_UNLOCK(&(pdu->lock));
1474
1475
 end:;
1476
  return rv;
1477
}
1478
1479
/*****************************************************************************/
1480
/* Server Audio Formats and Version PDU	*/
1481
static int APP_CC
1482
sound_SERVER_AUDIO_VERSION_AND_FORMATS_out(struct stream* s, SERVER_AUDIO_VERSION_AND_FORMATS *pdu) {
1483
1484
  unsigned int idx, lmt;
1485
1486
  if (verbose) {
1487
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1488
  }
1489
1490
    /* Header [RDPSND PDU Header] */
1491
  out_uint8(s, pdu->Header.msgType);		/* msgType [1 byte uint] = SNDC_FORMATS = 0x01 */
1492
  out_uint8(s, pdu->Header.bPad);		/* bPad [1 byte uint] = 0 */
1493
  out_uint16_le(s, pdu->Header.BodySize);	/* BodySize [2 bytes uint] = 0 */
1494
1495
    /* dwFlags [4 bytes uint] */
1496
  out_uint32_le(s, pdu->dwFlags);
1497
1498
    /* dwVolume [4 bytes uint] */
1499
  out_uint32_le(s, pdu->dwVolume);
1500
1501
    /* dwPitch [4 bytes uint] */
1502
  out_uint32_le(s, pdu->dwPitch);
1503
1504
    /* wDGramPort [2 bytes uint] */
1505
  out_uint16_le(s, pdu->wDGramPort);
1506
1507
    /* wNumberOfFormats [4 bytes uint] */
1508
  out_uint16_le(s, pdu->wNumberOfFormats);
1509
1510
    /* cLastBlockConfirmed [1 byte uint] */
1511
  out_uint8(s, pdu->cLastBlockConfirmed);
1512
1513
    /* wVersion [2 bytes uint] */
1514
  out_uint16_le(s, pdu->wVersion);
1515
1516
    /* bPad [1 byte uint] */
1517
  out_uint8(s, pdu->bPad);
1518
1519
  lmt = pdu->wNumberOfFormats;
1520
  for (idx = 0; idx < lmt ; idx++) {
1521
    sound_AUDIO_FORMAT_out(s, (AUDIO_FORMAT *)pdu->sndFormats[idx]);
1522
  }
1523
1524
  if (verbose) {
1525
    MDBGLOG("sound","INFO\t[%s()]: done.",__func__);
1526
  }
1527
1528
  return 0;
1529
}
1530
1531
1532
/*****************************************************************************/
1533
/* UNIX signal to quit recieved */
1534
static void exit_signal_callback(pa_mainloop_api * m, pa_signal_event * e, int sig, void * userdata) {
1535
    if (verbose) {
1536
      MDBGLOG("sound", "INFO\t[%s()]: received exit signal", __func__);
1537
    }
1538
    pa_quit(0);
1539
}
1540
1541
/*****************************************************************************/
1542
int APP_CC
1543
sound_init(void) {
1544
  struct stream * s = (struct stream *)NULL;
1545
  int size = 0;
1546
  int rv = 0;
1547
  int pid = 0;
1548
  SERVER_AUDIO_VERSION_AND_FORMATS tpdu;
1549
  SERVER_AUDIO_VERSION_AND_FORMATS * pdu = (SERVER_AUDIO_VERSION_AND_FORMATS *)(&tpdu);
1550
  WAVEFORMATEX afmt[7];
1551
  char * sockname = (char *)NULL;
1552
  char * uname = (char *)NULL;
1553
  char * udir = (char *)NULL;
1554
  char * audio_fifo_path = (char *)NULL;
1555
  char wait_socket[512];
1556
  char tbuf[512];
1557
  int fd = 0;
1558
  int cv = 0;
1559
  int locked = 0;
1560
  tbus sck = 0;
1561
  struct timeval ltime;
1562
  double t = 0.;
1563
1564
  if (g_attr == NULL) {
1565
    g_attr = (tc_p)(&mutex_attribute);
1566
    TC_MUTATTR_INIT(g_attr);
1567
    TC_MUTATTR_SETTYPE(g_attr,TC_MUTEX_ERRORCHECK);
1568
  }
1569
1570
  TC_MUTEX_INIT(&g_cb_mutex, g_attr);
1571
  TC_MUTEX_INIT(&g_init_mutex, g_attr);
1572
  TC_MUTEX_INIT(&g_drain_mutex, g_attr);
1573
  TC_MUTEX_INIT(&g_event_mutex, g_attr);
1574
  TC_MUTEX_INIT(&g_underrun_mutex, g_attr);
1575
  TC_MUTEX_INIT(&g_stream_mutex, g_attr);
1576
  TC_MUTEX_INIT(&g_thread_mutex, g_attr);
1577
  TC_MUTEX_INIT(&g_ready_mutex, g_attr);
1578
  TC_MUTEX_INIT(&g_stream_ready_mutex, g_attr);
1579
  TC_MUTEX_INIT(&g_pause_mutex, g_attr);
1580
  TC_MUTEX_INIT(&g_pause_ack_mutex, g_attr);
1581
  TC_MUTEX_INIT(&g_new_mutex, g_attr);
1582
  TC_MUTEX_INIT(&g_buffer_mutex, g_attr);
1583
  TC_MUTEX_INIT(&g_sink_mutex, g_attr);
1584
  TC_MUTEX_INIT(&g_pa_mutex, g_attr);
1585
  TC_MUTEX_INIT(&g_sound_mutex, g_attr);
1586
  TC_MUTEX_INIT(&g_ins_mutex, g_attr);
1587
  TC_MUTEX_INIT(&g_pktq_mutex, g_attr);
1588
  TC_MUTEX_INIT(&g_audio_mutex, g_attr);
1589
  TC_MUTEX_INIT(&g_up_mutex, g_attr);
1590
  TC_MUTEX_INIT(&g_close_mutex, g_attr);
1591
  TC_MUTEX_INIT(&g_pktready_mutex, g_attr);
1592
  TC_MUTEX_INIT(&g_train_mutex, g_attr);
1593
  TC_MUTEX_INIT(&g_send_mutex, g_attr);
1594
  TC_MUTEX_INIT(&g_socket_mutex, g_attr);
1595
  TC_MUTEX_INIT(&g_prev_mutex, g_attr);
1596
  TC_MUTEX_INIT(&g_formats_mutex, g_attr);
1597
  TC_MUTEX_INIT(&g_block_mutex, g_attr);
1598
1599
  {
1600
    barr_formats = &g_formats_barr;
1601
    g_memset(barr_formats,0,sizeof(tc_t));
1602
    TC_BARR_INIT(barr_formats, 2);
1603
  }
1604
1605
  if (mutex_sound == NULL) {
1606
    tc_t mattr;
1607
    tc_p pattr = &mattr;
1608
    mutex_sound = (tc_p)(&g_sound_mutex);
1609
    TC_MUTATTR_INIT(pattr);
1610
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1611
    TC_MUTEX_INIT(mutex_sound,pattr);
1612
  }
1613
1614
  if (mutex_sound != NULL) {
1615
    TC_MUTEX_LOCK(mutex_sound);
1616
    locked = 1;
1617
  }
1618
1619
  if (mutex_up == NULL) {
1620
    mutex_up = (tc_p)(&g_up_mutex);
1621
    TC_MUTEX_INIT(mutex_up,g_attr);
1622
  }
1623
1624
  TC_MUTEX_LOCK(mutex_up);
1625
  if (g_sound_up > 0) {
1626
    if (locked > 0 && mutex_sound != NULL) {
1627
      TC_MUTEX_UNLOCK(mutex_sound);
1628
    }
1629
    TC_MUTEX_UNLOCK(mutex_up);
1630
    return 0;
1631
  }
1632
  else {
1633
    TC_MUTEX_UNLOCK(mutex_up);
1634
  }
1635
  sound_deinit();
1636
1637
  if (verbose) {
1638
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
1639
  }
1640
1641
  rv = 0;
1642
  pid = g_getpid();
1643
1644
  if (mutex_thread == NULL) {
1645
    tc_t mattr;
1646
    tc_p pattr = &mattr;
1647
    mutex_thread = (tc_p)(&g_thread_mutex);
1648
    TC_MUTATTR_INIT(pattr);
1649
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1650
    TC_MUTEX_INIT(mutex_thread,pattr);
1651
  }
1652
1653
  if (mutex_pa == NULL) {
1654
    tc_t mattr;
1655
    tc_p pattr = &mattr;
1656
    mutex_pa = (tc_p)(&g_pa_mutex);
1657
    TC_MUTATTR_INIT(pattr);
1658
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1659
    TC_MUTEX_INIT(mutex_pa,pattr);
1660
  }
1661
1662
  if (mutex_ins == NULL) {
1663
    tc_t mattr;
1664
    tc_p pattr = &mattr;
1665
    mutex_ins = (tc_p)(&g_ins_mutex);
1666
    TC_MUTATTR_INIT(pattr);
1667
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1668
    TC_MUTEX_INIT(mutex_ins,pattr);
1669
  }
1670
1671
  if (mutex_pktq == NULL) {
1672
    tc_t mattr;
1673
    tc_p pattr = &mattr;
1674
    mutex_pktq = (tc_p)(&g_pktq_mutex);
1675
    TC_MUTATTR_INIT(pattr);
1676
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1677
    TC_MUTEX_INIT(mutex_pktq,pattr);
1678
  }
1679
1680
  if (mutex_audio == NULL) {
1681
    tc_t mattr;
1682
    tc_p pattr = &mattr;
1683
    mutex_audio = (tc_p)(&g_audio_mutex);
1684
    TC_MUTATTR_INIT(pattr);
1685
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1686
    TC_MUTEX_INIT(mutex_audio,pattr);
1687
  }
1688
1689
  if (mutex_ready == NULL) {
1690
    tc_t mattr;
1691
    tc_p pattr = &mattr;
1692
    mutex_ready = (tc_p)(&g_ready_mutex);
1693
    TC_MUTATTR_INIT(pattr);
1694
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1695
    TC_MUTEX_INIT(mutex_ready,pattr);
1696
  }
1697
1698
  if (mutex_stream_ready == NULL) {
1699
    tc_t mattr;
1700
    tc_p pattr = &mattr;
1701
    mutex_stream_ready = (tc_p)(&g_stream_ready_mutex);
1702
    TC_MUTATTR_INIT(pattr);
1703
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1704
    TC_MUTEX_INIT(mutex_stream_ready,pattr);
1705
  }
1706
1707
  if (mutex_pause == NULL) {
1708
    tc_t mattr;
1709
    tc_p pattr = &mattr;
1710
    mutex_pause = (tc_p)(&g_pause_mutex);
1711
    mutex_pause_ack = (tc_p)(&g_pause_ack_mutex);
1712
    g_memset(pattr,0,sizeof(tc_t));
1713
    TC_MUTATTR_INIT(pattr);
1714
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1715
    TC_MUTEX_INIT(mutex_pause,pattr);
1716
    TC_MUTEX_INIT(mutex_pause_ack,pattr);
1717
    g_memset(pattr,0,sizeof(tc_t));
1718
    cond_pause = (tc_p)(&g_pause_cond);
1719
    cond_pause_ack = (tc_p)(&g_pause_ack_cond);
1720
    TC_CONDATTR_INIT(pattr);
1721
    TC_COND_CREATE(cond_pause,pattr);
1722
    TC_COND_CREATE(cond_pause_ack,pattr);
1723
  }
1724
1725
  if (mutex_new == NULL) {
1726
    tc_t mattr;
1727
    tc_p pattr = &mattr;
1728
    mutex_new = (tc_p)(&g_new_mutex);
1729
    TC_MUTATTR_INIT(pattr);
1730
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1731
    TC_MUTEX_INIT(mutex_new,pattr);
1732
  }
1733
1734
  if (mutex_buffer == NULL) {
1735
    tc_t mattr;
1736
    tc_p pattr = &mattr;
1737
    mutex_buffer = (tc_p)(&g_buffer_mutex);
1738
    TC_MUTATTR_INIT(pattr);
1739
    TC_MUTATTR_SETTYPE(pattr,TC_MUTEX_ERRORCHECK);
1740
    TC_MUTEX_INIT(mutex_buffer,pattr);
1741
  }
1742
1743
  if (mutex_out == NULL) {
1744
    tc_t mattr;
1745
    tc_p pattr = &mattr;
1746
  }
1747
1748
  TC_MUTEX_LOCK(mutex_ready);
1749
  g_ready_waiting = 0;
1750
  g_ready_count = 0;
1751
  TC_MUTEX_UNLOCK(mutex_ready);
1752
1753
  if (cond_pa == NULL) {
1754
    tc_t cattr;
1755
    tc_p pattr = (tc_p)(&cattr);
1756
    cond_pa = (tc_p)(&g_pa_cond);
1757
    TC_CONDATTR_INIT(pattr);
1758
    TC_COND_CREATE(cond_pa,pattr);
1759
  }
1760
1761
  if (cond_ready == NULL) {
1762
    tc_t cattr;
1763
    tc_p pattr = (tc_p)(&cattr);
1764
    cond_ready = (tc_p)(&g_ready_cond);
1765
    TC_CONDATTR_INIT(pattr);
1766
    TC_COND_CREATE(cond_ready,pattr);
1767
  }
1768
1769
  if (cond_stream_ready == NULL) {
1770
    tc_t cattr;
1771
    tc_p pattr = (tc_p)(&cattr);
1772
    cond_stream_ready = (tc_p)(&g_stream_ready_cond);
1773
    TC_CONDATTR_INIT(pattr);
1774
    TC_COND_CREATE(cond_stream_ready,pattr);
1775
  }
1776
1777
  if (mutex_close == NULL) {
1778
    mutex_close = (tc_p)(&g_close_mutex);
1779
    TC_MUTEX_INIT(mutex_close,g_attr);
1780
  }
1781
1782
  TC_MUTEX_LOCK(mutex_close);
1783
  g_received_close_pdu = 0;
1784
  TC_MUTEX_UNLOCK(mutex_close);
1785
1786
  if (mutex_pktq == NULL) {
1787
    mutex_pktq = (tc_p)(&g_pktq_mutex);
1788
    TC_MUTEX_INIT(mutex_pktq,g_attr);
1789
  }
1790
1791
  if (mutex_pktlog == NULL) {
1792
    mutex_pktlog = (tc_p)(&g_pktlog_mutex);
1793
    TC_MUTEX_INIT(mutex_pktlog,g_attr);
1794
  }
1795
1796
  if (mutex_pktready == NULL) {
1797
    mutex_pktready = (tc_p)(&g_pktready_mutex);
1798
    TC_MUTEX_INIT(mutex_pktready,g_attr);
1799
  }
1800
1801
  if (mutex_train == NULL) {
1802
    mutex_train = (tc_p)(&g_train_mutex);
1803
    TC_MUTEX_INIT(mutex_train,g_attr);
1804
  }
1805
1806
  if (mutex_send == NULL) {
1807
    mutex_send = (tc_p)(&g_send_mutex);
1808
    TC_MUTEX_INIT(mutex_send,g_attr);
1809
  }
1810
1811
  if (mutex_socket == NULL) {
1812
    mutex_socket = (tc_p)(&g_socket_mutex);
1813
    TC_MUTEX_INIT(mutex_socket,g_attr);
1814
  }
1815
1816
  if (mutex_prev == NULL) {
1817
    mutex_prev = (tc_p)(&g_prev_mutex);
1818
    TC_MUTEX_INIT(mutex_prev,g_attr);
1819
  }
1820
1821
  if (mutex_formats == NULL) {
1822
    mutex_formats = (tc_p)(&g_formats_mutex);
1823
    TC_MUTEX_INIT(mutex_formats,g_attr);
1824
  }
1825
1826
  if (mutex_block == NULL) {
1827
    mutex_block = (tc_p)(&g_block_mutex);
1828
    TC_MUTEX_INIT(mutex_block,g_attr);
1829
  }
1830
1831
  if (thread_pktq == NULL) {
1832
    thread_pktq = (tc_p)(&g_pktq_thread);
1833
  }
1834
1835
  if (thread_pa == NULL) {
1836
    thread_pa = (tc_p)(&g_pa_thread);
1837
  }
1838
1839
  g_memset(&ltime,0,sizeof(struct timeval));
1840
  g_memset(selfpipe_path,0,(512 * sizeof(char)));
1841
  TC_MUTEX_LOCK(mutex_pktlog);
1842
  g_memset(pktlog,0,(MAX_PKTLOG * sizeof(pktinfo)));
1843
  TC_MUTEX_UNLOCK(mutex_pktlog);
1844
  g_memset(afmt,0,(7 * sizeof(WAVEFORMATEX)));
1845
  TC_MUTEX_LOCK(mutex_socket);
1846
  g_memset(wait_socket,0,(512 * sizeof(char)));
1847
  TC_MUTEX_UNLOCK(mutex_socket);
1848
  g_memset(tbuf,0,(512 * sizeof(char)));
1849
1850
#ifdef XRDP_ENABLE_SOXCONVERT
1851
  cv = g_soxconvert_init();
1852
  if (verbose) {
1853
    MDBGLOG("sound","g_soxconvert_init: %d\0",cv);
1854
  }
1855
#endif
1856
1857
  g_pktq = SOUND_NEW(pktq);
1858
1859
  audio_fifo_path = g_getenv("XRDP_AUDIO_FIFO");
1860
  if ((audio_fifo_path != NULL) && (g_strlen(audio_fifo_path) > 0)) {
1861
    sockname = g_strndup(audio_fifo_path, 128);
1862
  }
1863
  if (verbose) {
1864
    MDBGLOG("sound"," ^^ sockname=%s; audio_fifo_path=%s",sockname,audio_fifo_path);
1865
  }
1866
1867
  #ifndef L_cuserid
1868
  #define L_cuserid 17
1869
  #endif
1870
  uname = g_getenv("USER");
1871
  if ((uname == NULL) || (g_strlen(uname) < 1)) {
1872
    if (pid > -1) {
1873
      g_snprintf(tbuf,255,CHANSRV_USERNAME_PATH,pid);
1874
      fd = g_file_open(tbuf);
1875
      if (fd > -1) {
1876
	uname = (char *)g_malloc((sizeof(char) * 256),1);
1877
	g_file_read(fd, uname, 255);
1878
	g_file_close(fd);
1879
	fd = 0;
1880
      }
1881
    }
1882
  }
1883
  if ((uname == NULL) || (g_strlen(uname) < 1)) {
1884
    MDBGLOG("sound","ERROR\t[%s()]: unable to ascertain username",__func__);
1885
    rv = -1;
1886
    if (locked > 0) {
1887
      TC_MUTEX_UNLOCK(mutex_sound);
1888
    }
1889
    return rv;
1890
  }
1891
  else if ((sockname == NULL) || (g_strlen(sockname) < 1)) {
1892
#ifdef XRDP_ENABLE_PULSEAUDIO
1893
    udir = (char *)g_malloc(((g_strlen(uname) + g_strlen("/home//.pulse") + 1) * sizeof(char)),1);
1894
    g_snprintf(udir,((g_strlen(uname) + g_strlen("/home//.pulse") + 1) * sizeof(char)),"/home/%s/.pulse",uname);
1895
    sockname = get_audio_socket(udir);
1896
#endif
1897
  }
1898
  if (verbose) {
1899
    MDBGLOG("sound"," ^^ (1) sockname=%s",sockname);
1900
  }
1901
1902
  TC_MUTEX_LOCK(mutex_audio);
1903
#ifdef XRDP_ENABLE_ALSA
1904
  if ((g_audio == NULL) && ((audio_fifo_path == NULL) || (g_strlen(audio_fifo_path) < 1) || (g_file_exist(audio_fifo_path) < 1)) && ((sockname == NULL) || (g_strlen(sockname) < 1) || (g_file_exist(sockname) < 1))) {
1905
    sockname = g_strdup("/tmp/fifo-alsa-output");
1906
    cv = g_alsa_init();
1907
    if ((cv > -1) && (g_alsa != NULL)) {
1908
      g_alsa->setup_fifo(g_alsa,sockname);
1909
    }
1910
    MDBGLOG("sound"," ^^ g_alsa_init: %d\0",cv);
1911
  }
1912
  MDBGLOG("sound"," ^^ (2) sockname=%s\0",sockname);
1913
#endif
1914
1915
  g_memset(tbuf,0,sizeof(char) * 512);
1916
  g_snprintf(selfpipe_path,511,SELFPIPE_PATH,pid);
1917
  if (g_audio != NULL) {
1918
    MDBGLOG("sound","DEBUG\t[%s()]: calling trans_delete()",__func__);
1919
    trans_delete(g_audio);
1920
  }
1921
  if (g_audio_socket_type == WO_LOCAL) {
1922
    g_audio = trans_create(g_audio_socket_type, MAX_STREAM, MAX_STREAM);
1923
    g_audio->header_size = 0;
1924
    g_audio->callback_data = g_audio;
1925
    g_audio->ready = 1;
1926
    g_audio->rtime = 0.;
1927
    g_sound_wait_obj = g_create_wait_obj_from_socket(g_audio->sck, 1);
1928
  }
1929
  else if (g_audio_socket_type == WO_FIFO) {
1930
    g_audio = trans_create(g_audio_socket_type, MAX_STREAM, MAX_STREAM);
1931
    g_audio->header_size = 0;
1932
    g_audio->callback_data = g_audio;
1933
    g_audio->ready = 1;
1934
    g_audio->rtime = 0.;
1935
    g_sound_wait_obj = g_create_wait_obj_from_fifo(g_audio->sck,0);
1936
  }
1937
  TC_MUTEX_UNLOCK(mutex_audio);
1938
1939
  if (verbose) {
1940
    MDBGLOG("sound","INFO\t[%s()]: fd = %d; g_sound_wait_obj = %d",__func__,fd,g_sound_wait_obj);
1941
  }
1942
1943
  if (rv == 0) {
1944
    char * sndFormatArray[] = {"alaw", "msg723", "mp3", "mulaw", "ima_adpcm", "adpcm", "hipcm", "gsm610" };
1945
1946
    if (pdu == NULL) {
1947
      MDBGLOG("sound","ERROR\t[%s()]: pdu is NULL",__func__);
1948
      rv = 4;
1949
    }
1950
    else {
1951
      construct_SERVER_AUDIO_VERSION_AND_FORMATS(pdu, sndFormatArray, 8);
1952
      TC_MUTEX_LOCK(mutex_formats);
1953
      server_formats = pdu;
1954
      TC_MUTEX_UNLOCK(mutex_formats);
1955
1956
      make_stream(s);
1957
      if (s == NULL) {
1958
        MDBGLOG("sound","ERROR\t[%s()]: make_stream() failed",__func__);
1959
        rv = 4;
1960
      }
1961
      else {
1962
	tc_t * lt = (tc_t *)NULL;
1963
	tc_t tattr;
1964
	tc_p pattr = (tc_p)(&tattr);
1965
	g_memset(pattr,0,sizeof(tc_t));
1966
	lt = (tc_t *)g_malloc(sizeof(tc_t), 1);
1967
	TC_THREADATTR_INIT(pattr);
1968
	TC_THREADATTR_SETDETACHSTATE(pattr, TC_CREATE_JOINABLE);
1969
        init_stream(s, MAX_STREAM);
1970
        sound_SERVER_AUDIO_VERSION_AND_FORMATS_out(s, pdu);
1971
        s_mark_end(s);
1972
        size = (int)(s->end - s->data);
1973
	TC_MUTEX_LOCK(mutex_out);
1974
        rv = send_channel_data(g_rdpsnd_chan_id, s->data, size);
1975
	TC_MUTEX_UNLOCK(mutex_out);
1976
	TC_MUTEX_LOCK(mutex_thread);
1977
	TC_THREAD_INIT_FULL(&(lt->thread), (const tc_threadattr_t *)pattr, &sound_timer_loop, NULL);
1978
	TC_MUTEX_UNLOCK(mutex_thread);
1979
	if (rv != 0)
1980
        {
1981
          MDBGLOG("sound","ERROR\t[%s()]: send_channel_data() failed (rv = %d)",__func__,rv);
1982
          rv = 4;
1983
        }
1984
	free_stream(s);
1985
      }
1986
    }
1987
    //g_free(sndFormatArray[6]);
1988
    //g_free(sndFormatArray[5]);
1989
    //g_free(sndFormatArray[4]);
1990
    //g_free(sndFormatArray[3]);
1991
    //g_free(sndFormatArray[2]);
1992
    //g_free(sndFormatArray[1]);
1993
    //g_free(sndFormatArray[0]);
1994
    //g_free(sndFormatArray);
1995
  }
1996
1997
  /* spawn pktq thread: */
1998
  if (mutex_thread != NULL) {
1999
    tc_t tattr;
2000
    tc_p pattr = (tc_p)(&tattr);
2001
    g_memset(pattr,0,sizeof(tc_t));
2002
    TC_MUTEX_LOCK(mutex_thread);
2003
    TC_THREADATTR_INIT(pattr);
2004
    TC_THREADATTR_SETDETACHSTATE(pattr, TC_CREATE_JOINABLE);
2005
    TC_THREAD_INIT_FULL(&(thread_pktq->thread), (const tc_threadattr_t *)pattr, &sound_pktq_loop, NULL);
2006
    TC_MUTEX_UNLOCK(mutex_thread);
2007
  }
2008
2009
  /* spawn pulseaudio thread: */
2010
  if (mutex_pa != NULL) {
2011
    int tlocked = 0;
2012
    tc_t tattr;
2013
    tc_p pattr = (tc_p)(&tattr);
2014
    g_memset(pattr,0,sizeof(tc_t));
2015
    TC_MUTEX_LOCK(mutex_pa);
2016
    TC_THREADATTR_INIT(pattr);
2017
    TC_THREADATTR_SETDETACHSTATE(pattr, TC_CREATE_JOINABLE);
2018
    TC_THREAD_INIT_FULL(&(thread_pa->thread), (const tc_threadattr_t *)pattr, &sound_pa_start, NULL);
2019
    TC_MUTEX_UNLOCK(mutex_pa);
2020
  }
2021
2022
  if (rv == 0) {
2023
    if (0 && g_sound_up < 1) {
2024
      TC_MUTEX_LOCK(mutex_up);
2025
      if (g_sound_up < 1) {
2026
	g_sound_up = 1;
2027
      }
2028
      TC_MUTEX_UNLOCK(mutex_up);
2029
    }
2030
  }
2031
  else {
2032
    MDBGLOG("sound","ERROR\t[%s()]: error on exit (rv = %d)",__func__,rv);
2033
  }
2034
2035
  if (locked > 0) {
2036
    TC_MUTEX_UNLOCK(mutex_sound);
2037
  }
2038
  return rv;
2039
}
2040
2041
static void * APP_CC sound_pa_start(void * inarg) {
2042
    int ret = 0;
2043
    int done = 0;
2044
    int idx = 0;
2045
    unsigned int qcnt;
2046
    const char * server = (const char *)NULL;
2047
    const char client_name[] = "xrdpsnd";
2048
2049
    if (verbose) {
2050
      MDBGLOG("sound","INFO\t[%s()]: called",__func__);
2051
    }
2052
2053
    if (g_received_close_pdu > 0) {
2054
      goto exit;
2055
    }
2056
2057
    if (!g_pa_ready) {
2058
      TC_MUTEX_LOCK(mutex_pa);
2059
      if (!g_pa_ready) {
2060
	TC_COND_WAIT(cond_pa,mutex_pa);
2061
      }
2062
      TC_MUTEX_UNLOCK(mutex_pa);
2063
    }
2064
2065
    /* Set up a new main loop */
2066
    if (XRDP_THREADED_PA_MAINLOOP) {
2067
      if (!(mt = pa_threaded_mainloop_new())) {
2068
	MDBGLOG("sound", "ERROR\t[%s()]: pa_threaded_mainloop_new() failed.", __func__);
2069
	TC_MUTEX_UNLOCK(mutex_pa);
2070
	goto quit;
2071
      }
2072
      mainloop_api = pa_threaded_mainloop_get_api(mt);
2073
    }
2074
    else {
2075
      if (!(m = pa_mainloop_new())) {
2076
	MDBGLOG("sound", "ERROR\t[%s()]: pa_mainloop_new() failed.", __func__);
2077
	TC_MUTEX_UNLOCK(mutex_pa);
2078
	goto quit;
2079
      }
2080
      mainloop_api = pa_mainloop_get_api(m);
2081
    }
2082
2083
    if (mainloop_api == NULL) {
2084
	MDBGLOG("sound", "ERROR\t[%s()]: pa_mainloop_get_api() failed.", __func__);
2085
	TC_MUTEX_UNLOCK(mutex_pa);
2086
	goto quit;
2087
    }
2088
2089
    //pa_signal_new(SIGINT, pa_exit_signal_callback, NULL);
2090
    //pa_signal_new(SIGTERM, pa_exit_signal_callback, NULL);
2091
    //pa_disable_sigpipe();
2092
2093
    TC_MUTEX_LOCK(mutex_event);
2094
    if (!(stdio_event = mainloop_api->io_new(mainloop_api,
2095
	    mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,
2096
	    mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT,
2097
	    mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) {
2098
	TC_MUTEX_UNLOCK(mutex_event);
2099
	MDBGLOG("sound","ERROR\t[%s()]: io_new() failed",__func__);
2100
	goto quit;
2101
    }
2102
    TC_MUTEX_UNLOCK(mutex_event);
2103
2104
    if (0 && sound_get_pulseaudio_server(&server) < 0) {
2105
      MDBGLOG("sound","ERROR\t[%s()]: failed to ascertain PulseAudio server",__func__);
2106
      goto quit;
2107
    }
2108
    else do {
2109
      int tres = 0;
2110
      unsigned char tc = 0;
2111
      /* Create a new connection context */
2112
      if (!(context = pa_context_new(mainloop_api, client_name))) {
2113
        MDBGLOG("sound", "ERROR\t[%s()]: pa_context_new() failed.", __func__);
2114
	TC_MUTEX_UNLOCK(mutex_pa);
2115
        goto quit;
2116
      }
2117
      pa_context_set_state_callback(context, &context_state_callback, NULL);
2118
      pa_context_set_subscribe_callback(context, &pa_subscribe_cb, NULL);
2119
      TC_MUTEX_LOCK(mutex_init);
2120
      if (context != NULL && pa_context_get_state(context) != PA_CONTEXT_READY) { tres = pa_context_connect(context, server, PA_CONTEXT_NOFAIL, NULL); }
2121
      if (tres < 0) {
2122
	TC_MUTEX_UNLOCK(mutex_init);
2123
	MDBGLOG("sound", "ERROR\t[%s()]: pa_context_connect() failed: %s, trying again", __func__, pa_strerror(pa_context_errno(context)));
2124
	pa_xfree(context);
2125
	context = (pa_context *)NULL;
2126
	g_sleep(1000);
2127
      }
2128
      else {
2129
	TC_COND_WAIT(cond_init, mutex_init);
2130
	TC_MUTEX_UNLOCK(mutex_init);
2131
	break;
2132
      }
2133
      TC_MUTEX_UNLOCK(mutex_init);
2134
    } while (!(context != NULL && pa_context_get_state(context) == PA_CONTEXT_READY));
2135
2136
    TC_MUTEX_UNLOCK(mutex_pa);
2137
2138
    /* Start the PulseAudio mainloop thread */
2139
    if (XRDP_THREADED_PA_MAINLOOP) {
2140
      pa_threaded_mainloop_start(mt);
2141
      goto exit;
2142
    }
2143
2144
    quit:;
2145
      {
2146
        TC_MUTEX_LOCK(mutex_pa);
2147
	if (stream) {
2148
	  pa_stream_unref(stream);
2149
	}
2150
	if (context) {
2151
	  pa_context_unref(context);
2152
	}
2153
	TC_MUTEX_LOCK(mutex_event);
2154
	if (stdio_event) {
2155
	  assert(mainloop_api);
2156
	  mainloop_api->io_free(stdio_event);
2157
	}
2158
	TC_MUTEX_UNLOCK(mutex_event);
2159
	if (mt) {
2160
	  pa_signal_done();
2161
	  pa_threaded_mainloop_free(mt);
2162
	}
2163
	else if (m) {
2164
	  pa_signal_done();
2165
	  pa_mainloop_free(m);
2166
	}
2167
	pa_xfree(buffer);
2168
	pa_xfree(device);
2169
        TC_MUTEX_UNLOCK(mutex_pa);
2170
      }
2171
2172
  exit:;
2173
    if (verbose) {
2174
      MDBGLOG("sound","INFO\t[%s()]: done.",__func__);
2175
    }
2176
    TC_THREAD_EXIT(NULL);
2177
}
2178
2179
2180
/*****************************************************************************/
2181
static char * APP_CC
2182
get_audio_socket(const char * dirname) {
2183
  char * sub = (char *)NULL;
2184
  char * tmp = (char *)NULL;
2185
  char * ret = (char *)NULL;
2186
  char ** dirlist = (char **)NULL;
2187
  int dirlist_count = 0;
2188
  int idx = 0;
2189
  dirlist = g_dir_list_contents(dirname, dirlist, &dirlist_count);
2190
  while (idx < dirlist_count && tmp==NULL) {
2191
    sub = dirlist[idx];
2192
    tmp = g_strstr(sub,"runtime");
2193
    idx++;
2194
  }
2195
  tmp = sub;
2196
  idx = g_strlen(dirname) + g_strlen("/") + g_strlen(tmp) + g_strlen("/fifo_output") + 4;
2197
  ret = (char *)g_malloc((sizeof(char) * idx),1);
2198
  g_snprintf(ret,idx,"%s/%s/%s\0",dirname,tmp,"fifo_output");
2199
  return ret;
2200
}
2201
2202
2203
/*****************************************************************************/
2204
static int APP_CC
2205
closeAudio() {
2206
  int rv = 0;
2207
  int size = 0;
2208
  SNDCLOSE * pdu = (SNDCLOSE *)NULL;
2209
  LOCAL_STREAM(s);
2210
2211
  MDBGLOG("sound","INFO\t[%s()]: called",__func__);
2212
2213
  pdu = SOUND_NEW(SNDCLOSE);
2214
  sound_SNDCLOSE_out(s, pdu);
2215
  s_mark_end(s);
2216
  size = (int)(s->end - s->data);
2217
  TC_MUTEX_LOCK(mutex_out);
2218
  rv = send_channel_data(g_rdpsnd_chan_id, s->data, size);
2219
  TC_MUTEX_UNLOCK(mutex_out);
2220
  SOUND_FREE(pdu);
2221
2222
  return 0;
2223
}
2224
2225
/*****************************************************************************/
2226
int APP_CC sound_deinit() {
2227
  int cv = 0;
2228
2229
  if (verbose) {
2230
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
2231
  }
2232
2233
  //cv = g_alsa_deinit();
2234
  //MDBGLOG("sound","g_alsa_deinit: %d",cv);
2235
  //unlink(ALSAFIFO_PATH);
2236
2237
  g_received_close_pdu = 1;
2238
2239
  g_sleep(150);
2240
2241
  if (g_sound_up && cond_ready != NULL) {
2242
    TC_MUTEX_LOCK(mutex_ready);
2243
    if (g_ready_waiting > 0) {
2244
      if (g_ready_waiting > 0) {
2245
	TC_COND_BROADCAST(cond_ready);
2246
      }
2247
      else {
2248
	TC_COND_SIGNAL(cond_ready);
2249
      }
2250
      g_sleep(150);
2251
    }
2252
    TC_MUTEX_UNLOCK(mutex_ready);
2253
    g_sleep(150);
2254
    //pa_quit(0);
2255
  }
2256
2257
  if (mutex_thread != NULL) {
2258
    TC_MUTEX_LOCK(mutex_thread);
2259
    if (thread_pktq != NULL) {
2260
      TC_THREAD_KILL(thread_pktq->thread);
2261
      g_sleep(100);
2262
      //TC_THREAD_JOIN(thread_pktq->thread, NULL);
2263
      thread_pktq = (tc_p)NULL;
2264
    }
2265
    if (thread_pa != NULL) {
2266
      TC_THREAD_KILL(thread_pa->thread);
2267
      g_sleep(100);
2268
      //TC_THREAD_JOIN(thread_pa->thread, NULL);
2269
      thread_pa = (tc_p)NULL;
2270
    }
2271
    TC_MUTEX_UNLOCK(mutex_thread);
2272
    TC_MUTEX_DEINIT(mutex_thread);
2273
    mutex_thread = (tc_p)NULL;
2274
  }
2275
2276
  if (mutex_pa != NULL) {
2277
    TC_MUTEX_LOCK(mutex_pa);
2278
    if (thread_pa != NULL) {
2279
      TC_THREAD_JOIN(thread_pa->thread, NULL);
2280
      thread_pa = (tc_p)NULL;
2281
    }
2282
    TC_MUTEX_UNLOCK(mutex_pa);
2283
    TC_MUTEX_DEINIT(mutex_pa);
2284
    mutex_pa = (tc_p)NULL;
2285
  }
2286
2287
  TC_MUTEX_LOCK(mutex_up);
2288
  if (g_sound_up > 0) {
2289
    TC_MUTEX_UNLOCK(mutex_up);
2290
    TC_MUTEX_LOCK(mutex_close);
2291
    if (g_received_close_pdu == 0) { closeAudio(); }
2292
    TC_MUTEX_UNLOCK(mutex_close);
2293
    TC_MUTEX_LOCK(mutex_formats);
2294
    TC_MUTEX_UNLOCK(mutex_formats);
2295
  }
2296
  else {
2297
    TC_MUTEX_UNLOCK(mutex_up);
2298
  }
2299
2300
  TC_MUTEX_LOCK(mutex_socket);
2301
  if (g_sound_wait_obj > -1) {
2302
    g_delete_wait_obj(g_sound_wait_obj);
2303
    g_sound_wait_obj = -1;
2304
  }
2305
  if (g_sound_selfpipe > -1) {
2306
    g_delete_wait_obj(g_sound_selfpipe);
2307
    unlink(selfpipe_path);
2308
    g_sound_selfpipe = -1;
2309
  }
2310
  TC_MUTEX_UNLOCK(mutex_socket);
2311
2312
  TC_MUTEX_LOCK(mutex_up);
2313
  if (g_sound_up > 0) {
2314
    TC_MUTEX_UNLOCK(mutex_up);
2315
    TC_MUTEX_LOCK(mutex_socket);
2316
    if (g_sound_socket > -1) {
2317
      g_file_close(g_sound_socket);
2318
    }
2319
    g_sound_socket = -1;
2320
    TC_MUTEX_UNLOCK(mutex_socket);
2321
    TC_MUTEX_LOCK(mutex_ins);
2322
    if (g_ins != NULL) { free_stream(g_ins); }
2323
    g_ins = NULL;
2324
    TC_MUTEX_UNLOCK(mutex_ins);
2325
    TC_MUTEX_LOCK(mutex_pktq);
2326
    if (g_pktq != NULL) { SOUND_FREE(g_pktq); }
2327
    g_pktq = NULL;
2328
    TC_MUTEX_UNLOCK(mutex_pktq);
2329
    TC_MUTEX_LOCK(mutex_up);
2330
    g_sound_up = 0;
2331
    TC_MUTEX_UNLOCK(mutex_up);
2332
  }
2333
  else {
2334
    TC_MUTEX_UNLOCK(mutex_up);
2335
  }
2336
2337
  if (verbose) {
2338
    MDBGLOG("sound","INFO\t[%s()]: done.",__func__);
2339
  }
2340
  return 0;
2341
}
2342
2343
/*****************************************************************************/
2344
static int APP_CC
2345
trainAudio() {
2346
  int rv = 0;
2347
  int size = 0;
2348
  SNDTRAINING *pdu = (SNDTRAINING *)NULL;
2349
  LOCAL_STREAM(s);
2350
2351
  if (verbose) {
2352
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
2353
  }
2354
2355
  //TC_MUTEX_LOCK(mutex_new);
2356
  pdu = SOUND_NEW(SNDTRAINING);
2357
  //TC_MUTEX_UNLOCK(mutex_new);
2358
  
2359
  sound_SNDTRAINING_out(s, pdu);
2360
  s_mark_end(s);
2361
  size = (int)(s->end - s->data);
2362
2363
  TC_MUTEX_LOCK(mutex_sound);
2364
  TC_MUTEX_LOCK(mutex_out);
2365
  rv = send_channel_data(g_rdpsnd_chan_id, s->data, size);
2366
  TC_MUTEX_UNLOCK(mutex_out);
2367
  TC_MUTEX_UNLOCK(mutex_sound);
2368
2369
  SOUND_FREE(pdu);
2370
2371
  return 0;
2372
}
2373
2374
/*****************************************************************************/
2375
static unsigned int APP_CC
2376
flength(FILE *fp) {
2377
  BYTE *buf = NULL;
2378
  unsigned int res = 0;
2379
2380
  if (fp != NULL) {
2381
    fseek(fp, 0, SEEK_END);
2382
    res = ftell(fp);
2383
    rewind(fp);
2384
  }
2385
2386
  return res;  
2387
}
2388
2389
2390
/*****************************************************************************/
2391
int APP_CC
2392
sound_data_in(struct stream * s, int chan_id, int chan_flags, int length, int total_length) {
2393
  int rv = 0;
2394
  int size = 0;
2395
  int lidx = -1;
2396
  int ins_locked = 0;
2397
  struct stream * ls = (struct stream *)NULL;
2398
  SNDPROLOG hdr;
2399
  void * inPDU = (void *)NULL;
2400
  unsigned int idx = 0;
2401
  unsigned int lmt = 0;
2402
  CLIENT_AUDIO_VERSION_AND_FORMATS tmp;
2403
  AUDIO_FORMAT * ltmp = (AUDIO_FORMAT *)NULL;
2404
  AUDIO_FORMAT * afmt = (AUDIO_FORMAT *)NULL;
2405
2406
  if (verbose) {
2407
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
2408
  }
2409
2410
  g_memset(&hdr,0,sizeof(SNDPROLOG));
2411
  g_memset(&tmp,0,sizeof(CLIENT_AUDIO_VERSION_AND_FORMATS));
2412
2413
  if ((chan_flags & 3) == 3) {
2414
    ls = s;
2415
  }
2416
  else {
2417
    TC_MUTEX_LOCK(mutex_ins);
2418
    ins_locked = 1;
2419
    if (chan_flags & 1) {
2420
    }
2421
    if ((chan_flags & 2) == 0) {
2422
      TC_MUTEX_UNLOCK(mutex_ins);
2423
      ins_locked = 0;
2424
      return 0;
2425
    }
2426
    g_ins = s;
2427
    ls = g_ins;
2428
  }
2429
2430
  rv = 0;
2431
  sound_SNDPROLOG_in(ls, &hdr);
2432
  switch (hdr.msgType) {
2433
    case 0x01: /* SNDC_CLOSE: Close PDU */
2434
      rv = sound_process_SNDC_CLOSE(ls, &hdr);
2435
      break;
2436
    case 0x02: /* SNDC_WAVE: WaveInfo PDU */
2437
      break;
2438
    case 0x03: /* SNDC_SETVOLUME: Volume PDU */
2439
      break;
2440
    case 0x04: /* SNDC_SETPITCH: Pitch PDU */
2441
      break;
2442
    case 0x05: /* SNDC_WAVECONFIRM: Wave Confirm PDU */
2443
      inPDU = SOUND_NEW(SNDWAV_CONFIRM);
2444
      rv = sound_process_SNDC_WAVECONFIRM(ls, &hdr, (SNDWAV_CONFIRM *)inPDU);
2445
      TC_MUTEX_LOCK(mutex_drain);
2446
      if (cond_drain != NULL && g_drain > 0 && (g_outstanding < 1 || g_outstanding_playtime < g_target_latency)) {
2447
	TC_COND_SIGNAL(cond_drain);
2448
      }
2449
      TC_MUTEX_UNLOCK(mutex_drain);
2450
      if (inPDU != NULL && !g_callee_frees) {
2451
        if (((SNDWAV_CONFIRM *)inPDU)->__destructor != NULL) {
2452
	  ((SNDWAV_CONFIRM *)inPDU)->__destructor(inPDU);
2453
        }
2454
        else {
2455
	  g_free(inPDU);
2456
        }
2457
        inPDU = NULL;
2458
      }
2459
      break;
2460
    case 0x06: /* SNDC_TRAINING: Training PDU or Training Confirm PDU */
2461
      inPDU = SOUND_NEW(SNDTRAININGCONFIRM);
2462
      rv = sound_process_SNDC_TRAININGCONFIRM(ls, &hdr, (SNDTRAININGCONFIRM *)inPDU);
2463
      if (rv == 0) {
2464
	TC_MUTEX_LOCK(mutex_send);
2465
	g_sound_ready_to_send = 1;
2466
	TC_MUTEX_UNLOCK(mutex_send);
2467
      }
2468
      if (inPDU != NULL && !g_callee_frees) {
2469
	if (inPDU != NULL && ((SNDTRAININGCONFIRM *)inPDU)->__destructor != NULL) {
2470
	  ((SNDTRAININGCONFIRM *)inPDU)->__destructor(inPDU);
2471
	}
2472
	else {
2473
	  g_free(inPDU);
2474
	}
2475
	inPDU = NULL;
2476
      }
2477
      break;
2478
    case 0x07: /* SNDC_FORMATS: Server Audio Formats and Version PDU or Client Audio Formats and Version PDU */
2479
      inPDU = SOUND_NEW(CLIENT_AUDIO_VERSION_AND_FORMATS);
2480
      TC_MUTEX_LOCK(mutex_formats);
2481
      g_client_formats_received = 1;
2482
      client_formats = (CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU;
2483
      rv = sound_process_SNDC_FORMATS(ls, &hdr, client_formats);
2484
      construct_CLIENT_AUDIO_VERSION_AND_FORMATS(client_formats);
2485
      lmt = client_formats->wNumberOfFormats;
2486
      g_client_format_count += lmt;
2487
      TC_MUTEX_UNLOCK(mutex_formats);
2488
      for (idx=0;idx<lmt;idx++) {
2489
	MDBGLOG("sound","INFO\t[%s()]:",__func__);
2490
	MDBGLOG("sound"," >>>> [Format #%d]",(idx + 1));
2491
	MDBGLOG("sound"," >>>>  * wFormatTag: 0x%8.8x\0",((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->wFormatTag);
2492
	MDBGLOG("sound"," >>>>  * nChannels: %d\0",((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->nChannels);
2493
	MDBGLOG("sound"," >>>>  * nBlockAlign: %d\0",((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->nBlockAlign);
2494
	MDBGLOG("sound"," >>>>  * nSamplesPerSec: %d\0",((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->nSamplesPerSec);
2495
	MDBGLOG("sound"," >>>>  * nAvgBytesPerSec: %d\0",((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->nAvgBytesPerSec);
2496
	MDBGLOG("sound"," >>>>  * wBitsPerSample: %d\0",((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->wBitsPerSample);
2497
	MDBGLOG("sound"," >>>>  * cbSize: %d\n",((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->cbSize);
2498
	if (((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->wFormatTag == g_preferred_wave_format) {
2499
	  if (verbose) {
2500
	    MDBGLOG("sound","DEBUG\t[%s()]: found (idx = %d, wFormatTag = 0x%8.8x)",__func__,idx,((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx]->wFormatTag);
2501
	  }
2502
	  ltmp = ((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[idx];
2503
	  lidx = idx;
2504
	}
2505
      }
2506
      if ((lidx > -1) && (ltmp != NULL) && (client_formats != NULL) && (client_formats->sndFormats != NULL) && (client_formats->sndFormats[lidx] != NULL)) {
2507
	TC_MUTEX_LOCK(mutex_formats);
2508
	g_client_format_index = lidx;
2509
	g_client_format = client_formats->sndFormats[g_client_format_index]->wFormatTag;
2510
	g_format_byte_rate = ltmp->nAvgBytesPerSec;
2511
	TC_MUTEX_UNLOCK(mutex_formats);
2512
	MDBGLOG("sound","DEBUG\t[%s()]: found [final] (lidx = %d, wFormatTag = 0x%8.8x)",__func__,lidx,((CLIENT_AUDIO_VERSION_AND_FORMATS *)inPDU)->sndFormats[lidx]->wFormatTag);
2513
      }
2514
      TC_MUTEX_LOCK(mutex_train);
2515
      g_sound_ready_to_train = 1;
2516
      TC_MUTEX_UNLOCK(mutex_train);
2517
      TC_BARR_WAIT(barr_formats);
2518
      break;
2519
    case 0x08: /* SNDC_CRYPTKEY: Crypt Key PDU */
2520
      break;
2521
    case 0x09: /* SNDC_WAVEENCRYPT: Wave Encrypt PDU */
2522
      break;
2523
    case 0x0A: /* SNDC_UDPWAVE: UDP Wave PDU */
2524
      break;
2525
    case 0x0B: /* SNDC_UDPWAVELAST: UDP Wave Last PDU */
2526
      break;
2527
    case 0x0C: /* SNDC_QUALITYMODE: Quality Mode PDU */
2528
      inPDU = SOUND_NEW(QUALITY_MODE);
2529
      rv = sound_process_SNDC_QUALITYMODE(ls, &hdr, (QUALITY_MODE *)inPDU);
2530
      break;
2531
    default:
2532
      MDBGLOG("sound", "WARNING\t[%s()]: unknown hdr.msgType (%d)", __func__, hdr.msgType);
2533
      break;
2534
  }
2535
2536
  if (ins_locked > 0) {
2537
    TC_MUTEX_UNLOCK(mutex_ins);
2538
  }
2539
2540
  return rv;
2541
}
2542
2543
/*****************************************************************************/
2544
int APP_CC
2545
sound_get_wait_objs(tbus * objs, int * count, int * timeout)
2546
{
2547
  int lcount = 0;
2548
  int res = 0;
2549
  if (g_received_close_pdu > 0) {
2550
    goto exit;
2551
  }
2552
  TC_MUTEX_LOCK(mutex_up);
2553
  TC_MUTEX_LOCK(mutex_pktq);
2554
  if ((g_sound_up == 0) || (objs == 0) || (count == 0) || (g_pktq == NULL))
2555
  {
2556
    TC_MUTEX_UNLOCK(mutex_pktq);
2557
    TC_MUTEX_UNLOCK(mutex_up);
2558
    res = 0;
2559
  }
2560
  else {
2561
    TC_MUTEX_UNLOCK(mutex_pktq);
2562
    TC_MUTEX_UNLOCK(mutex_up);
2563
    lcount = (*count);
2564
    TC_MUTEX_LOCK(mutex_socket);
2565
    if (g_sound_wait_obj > -1) {
2566
      TC_MUTEX_LOCK(mutex_send);
2567
      TC_MUTEX_LOCK(mutex_pktq);
2568
      if (g_sound_ready_to_send > 0 && g_pktq != NULL && g_pktq->getCount != NULL && g_pktq->getCount(g_pktq) > 0 && g_sound_wait_obj > -1) {
2569
	objs[lcount] = g_sound_wait_obj;
2570
	lcount++;
2571
      }
2572
      TC_MUTEX_UNLOCK(mutex_pktq);
2573
      TC_MUTEX_UNLOCK(mutex_send);
2574
    }
2575
    TC_MUTEX_UNLOCK(mutex_socket);
2576
    *count += lcount;
2577
    res = 0;
2578
  }
2579
 exit:;
2580
  return res;
2581
}
2582
2583
/*****************************************************************************/
2584
int APP_CC
2585
sound_check_wait_objs(void) {
2586
  int rv = 0;
2587
  if (g_received_close_pdu > 0) {
2588
    goto exit;
2589
  }
2590
  TC_MUTEX_LOCK(mutex_up);
2591
  if (!g_sound_up || g_pktq == NULL) {
2592
    TC_MUTEX_UNLOCK(mutex_up);
2593
    rv = 0;
2594
  }
2595
  else {
2596
    TC_MUTEX_UNLOCK(mutex_up);
2597
    TC_MUTEX_LOCK(mutex_send);
2598
    if (g_sound_ready_to_send > 0) {
2599
      TC_MUTEX_UNLOCK(mutex_send);
2600
      TC_MUTEX_LOCK(mutex_socket);
2601
      if (g_sound_wait_obj > -1 && g_is_wait_obj_set(g_sound_wait_obj)) {
2602
	TC_MUTEX_UNLOCK(mutex_socket);
2603
	TC_MUTEX_LOCK(mutex_audio);
2604
	trans_check_wait_objs(g_audio);
2605
	TC_MUTEX_UNLOCK(mutex_audio);
2606
      }
2607
      else {
2608
	TC_MUTEX_UNLOCK(mutex_socket);
2609
      }
2610
    }
2611
    else {
2612
      TC_MUTEX_UNLOCK(mutex_send);
2613
    }
2614
    rv = 0;
2615
  }
2616
 exit:;
2617
  return rv;
2618
}
2619
2620
/*****************************************************************************/
2621
static void * APP_CC
2622
sound_pktq_loop(void * inarg) {
2623
  int rv = 0;
2624
  int tmp = 0;
2625
  int qcnt = 0;
2626
  int done = 0;
2627
  int empty = 0;
2628
  int idle_count = 0;
2629
  size_t size = 0;
2630
  struct stream * ls = (struct stream *)NULL;
2631
  struct stream * ms = (struct stream *)NULL;
2632
  pkt * packet = (pkt *)NULL;
2633
  struct timeval time;
2634
  double t = 0.;
2635
  double dt = 0.;
2636
  double dtmp = 0.;
2637
  unsigned char plock = 0;
2638
  const unsigned int max_idle = 20;
2639
  long int ttime = 0;
2640
  long int tdiff = 0;
2641
  BYTE buf[1] = { 0 };
2642
2643
  if (verbose) {
2644
    MDBGLOG("sound","INFO\t[%s()]: called [%d, %d]",__func__,g_getpid(),g_gettid());
2645
  }
2646
2647
  if (g_received_close_pdu > 0) {
2648
    goto exit;
2649
  }
2650
2651
  TC_MUTEX_LOCK(mutex_pa);
2652
  TC_COND_WAIT(cond_pa,mutex_pa);
2653
  TC_MUTEX_UNLOCK(mutex_pa);
2654
2655
  g_memset(&time,0,sizeof(struct timeval));
2656
  done = 0;
2657
2658
  TC_MUTEX_LOCK(mutex_close);
2659
  done = g_received_close_pdu;
2660
  TC_MUTEX_UNLOCK(mutex_close);
2661
2662
  while (!done) {
2663
    MB;
2664
    if (!g_thunk && (g_stream_ready < 1 || g_sound_up < 1 || (g_sound_up > 0 && g_stream_ready > 0 && g_outstanding_playtime > g_max_latency))) {
2665
      unsigned char proceed = 0;
2666
      if (mutex_stream_ready != NULL && cond_stream_ready != NULL) {
2667
	TC_MUTEX_LOCK(mutex_stream_ready);
2668
	if (g_stream_ready < 1) {
2669
	  TC_COND_WAIT(cond_stream_ready, mutex_stream_ready);
2670
	  proceed = 1;
2671
	  TC_MUTEX_UNLOCK(mutex_stream_ready);
2672
	  if (1 || verbose) {
2673
	    MDBGLOG("sound","DEBUG\t[%s()]: woken up",__func__);
2674
	  }
2675
	}
2676
	else if (g_enable_skew_compensation > 0) {
2677
	  if (g_outstanding_playtime > g_max_latency) {
2678
	    TC_MUTEX_UNLOCK(mutex_stream_ready);
2679
	    g_sleep(180);
2680
	  }
2681
	}
2682
      }
2683
      if (g_enable_skew_compensation > 0 && g_stream_ready > 0 && g_sound_up > 0 && g_outstanding_playtime > g_max_latency) {
2684
	TC_MUTEX_LOCK(mutex_drain);
2685
	if (g_stream_ready > 0 && g_sound_up > 0 && (g_outstanding_playtime > g_max_latency)) {
2686
	  tc_t pattr;
2687
	  tc_t * attr = &pattr;
2688
	  TC_CONDATTR_INIT(attr);
2689
	  TC_COND_CREATE(cond_drain, attr);
2690
	  if (1 || verbose) {
2691
	    MDBGLOG("sound","DEBUG\t[%s()]: waiting to drain...",__func__);
2692
	  }
2693
	  ttime = g_time2();
2694
	  g_drain = 1;
2695
	  TC_COND_TIMEDWAIT(cond_drain, mutex_drain, g_max_latency);
2696
	  tdiff = g_time2() - ttime;
2697
	  g_drain = 0;
2698
	  if (1 || verbose) {
2699
	    MDBGLOG("sound","DEBUG\t[%s()]: drained. (tdiff = %d)",__func__,tdiff);
2700
	  }
2701
	}
2702
	TC_MUTEX_UNLOCK(mutex_drain);
2703
	proceed = 0;
2704
      }
2705
      else if (g_enable_skew_compensation > 0 && g_stream_ready > 0 && g_sound_up > 0 && g_outstanding_playtime > g_high_latency) {
2706
	g_sleep(g_target_latency);
2707
      }
2708
      else if (g_enable_skew_compensation > 0 && g_stream_ready > 0 && g_sound_up > 0 && g_outstanding_playtime > g_target_latency) {
2709
	g_sleep(g_target_latency / 2);
2710
	//proceed = 1;
2711
      }
2712
      if (!proceed) {
2713
	TC_MUTEX_LOCK(mutex_close);
2714
	done = g_received_close_pdu;
2715
	TC_MUTEX_UNLOCK(mutex_close);
2716
	continue;
2717
      }
2718
    }
2719
    if (idle_count > max_idle && g_sound_up > 0 && g_sound_ready_to_send > 0 && g_ready_count < 1) {
2720
      tc_t cattr;
2721
      tc_p pattr = (tc_p)(&cattr);
2722
      g_memset(pattr,0,sizeof(tc_t));
2723
      TC_CONDATTR_INIT(pattr);
2724
      TC_MUTEX_LOCK(mutex_ready);
2725
      if (g_ready_count > 0) {
2726
	TC_MUTEX_UNLOCK(mutex_ready);
2727
	TC_MUTEX_LOCK(mutex_close);
2728
	done = g_received_close_pdu;
2729
	TC_MUTEX_UNLOCK(mutex_close);
2730
	continue;
2731
      }
2732
      cond_ready = &g_ready_cond;
2733
      g_ready_triggered = 0;
2734
      TC_COND_CREATE(cond_ready, pattr);
2735
      if (g_ready_count < 1) {
2736
	TC_MUTEX_UNLOCK(mutex_ready);
2737
	TC_MUTEX_LOCK(mutex_ready);
2738
      }
2739
      if (g_ready_count < 1) {
2740
	g_ready_waiting++;
2741
	g_idle = 1;
2742
	if (1 || verbose) {
2743
	  MDBGLOG("sound","DEBUG\t[%s()]: waiting...",__func__);
2744
	}
2745
	ttime = g_time2();
2746
	TC_COND_WAIT(cond_ready, mutex_ready);
2747
	tdiff = g_time2() - ttime;
2748
	if (1 || verbose) {
2749
	  MDBGLOG("sound","DEBUG\t[%s()]: finished (tdiff = %d)",__func__,tdiff);
2750
	}
2751
	g_ready_waiting--;
2752
      }
2753
      g_idle = 0;
2754
      if (g_ready_count < 1) {
2755
	TC_MUTEX_UNLOCK(mutex_ready);
2756
	TC_MUTEX_LOCK(mutex_close);
2757
	done = g_received_close_pdu;
2758
	TC_MUTEX_UNLOCK(mutex_close);
2759
	continue;
2760
      }
2761
      else if (!g_ready_triggered) {
2762
	TC_MUTEX_LOCK(mutex_pktq);
2763
	if (g_pktq != NULL && g_pktq->deq != NULL && g_pktq->getCount != NULL) {
2764
	  qcnt = g_pktq->getCount(g_pktq);
2765
	  if (qcnt > 0) {
2766
	    packet = g_pktq->deq(g_pktq);
2767
	    if (packet != NULL) {
2768
	      g_ready_count--;
2769
	      idle_count = 0;
2770
	      TC_MUTEX_LOCK(&(packet->lock));
2771
	      g_ready_playbytes -= packet->byteCount;
2772
	      g_ready_playtime = (g_ready_playbytes > 0) ? pa_bytes_to_usec(g_ready_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
2773
	      g_ready_playtime *= 1;
2774
	      plock = 1;
2775
	    }
2776
	    else {
2777
	      reset_pktq(g_pktq);
2778
	    }
2779
	  }
2780
	  else {
2781
	    TC_MUTEX_UNLOCK(mutex_pktq);
2782
	    TC_MUTEX_UNLOCK(mutex_ready);
2783
	    idle_count++;
2784
	    TC_MUTEX_LOCK(mutex_close);
2785
	    done = g_received_close_pdu;
2786
	    TC_MUTEX_UNLOCK(mutex_close);
2787
	    continue;
2788
	  }
2789
	}
2790
	TC_MUTEX_UNLOCK(mutex_pktq);
2791
	TC_MUTEX_UNLOCK(mutex_ready);
2792
      }
2793
      else {
2794
	if (g_pktq != NULL && g_pktq->deq != NULL && g_pktq->getCount != NULL) {
2795
	  TC_MUTEX_LOCK(mutex_pktq);
2796
	  qcnt = g_pktq->getCount(g_pktq);
2797
	  if (qcnt > 0) {
2798
	    packet = g_pktq->deq(g_pktq);
2799
	    if (packet != NULL) {
2800
	      g_ready_count--;
2801
	      idle_count = 0;
2802
	      TC_MUTEX_LOCK(&(packet->lock));
2803
	      g_ready_playbytes -= packet->byteCount;
2804
	      g_ready_playtime = (g_ready_playbytes > 0) ? pa_bytes_to_usec(g_ready_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
2805
	      g_ready_playtime *= 1;
2806
	      plock = 1;
2807
	    }
2808
	    else {
2809
	      reset_pktq(g_pktq);
2810
	    }
2811
	  }
2812
	  TC_MUTEX_UNLOCK(mutex_pktq);
2813
	}
2814
	else {
2815
	  MDBGLOG("sound","ERROR\t[%s()]: g_pktq = %p",__func__,g_pktq);
2816
	}
2817
	if (verbose) {
2818
	  MDBGLOG("sound","INFO\t[%s()]: packet = %p, qcnt = %d",__func__,packet,qcnt);
2819
	  MDBGLOG("sound","DEBUG\t[%s()]: g_ready_triggered = %d, g_ready_triggered_count = %d",__func__,g_ready_triggered,g_ready_triggered_count);
2820
	}
2821
	g_ready_triggered_count++;
2822
	g_ready_triggered = 0;
2823
	TC_MUTEX_UNLOCK(mutex_ready);
2824
      }
2825
    }
2826
    else {
2827
      TC_MUTEX_LOCK(mutex_up);
2828
      TC_MUTEX_LOCK(mutex_send);
2829
      if (g_sound_up > 0 && g_sound_ready_to_send > 0) {
2830
	TC_MUTEX_UNLOCK(mutex_send);
2831
	TC_MUTEX_UNLOCK(mutex_up);
2832
	TC_MUTEX_LOCK(mutex_pktq);
2833
	if (g_pktq != NULL && g_pktq->deq != NULL && g_pktq->getCount != NULL) {
2834
	  qcnt = g_pktq->getCount(g_pktq);
2835
	  if (qcnt > 0) {
2836
	    packet = g_pktq->deq(g_pktq);
2837
	    if (packet != NULL) {
2838
	      g_ready_count--;
2839
	      idle_count = 0;
2840
	      TC_MUTEX_LOCK(&(packet->lock));
2841
	      plock = 1;
2842
	      g_ready_playbytes -= packet->byteCount;
2843
	      g_ready_playtime = (g_ready_playbytes > 0) ? pa_bytes_to_usec(g_ready_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
2844
	      g_ready_playtime *= 1;
2845
	    }
2846
	    else {
2847
	      reset_pktq(g_pktq);
2848
	    }
2849
	  }
2850
	  else {
2851
	    idle_count++;
2852
	  }
2853
	}
2854
	else {
2855
	  MDBGLOG("sound","ERROR\t[%s()]: g_pktq = %p",__func__,g_pktq);
2856
	}
2857
	TC_MUTEX_UNLOCK(mutex_pktq);
2858
      }
2859
      else {
2860
	TC_MUTEX_UNLOCK(mutex_send);
2861
	TC_MUTEX_UNLOCK(mutex_up);
2862
      }
2863
    }
2864
    TC_MUTEX_LOCK(mutex_up);
2865
    if (!g_sound_up || g_pktq == NULL || g_pktq->deq == NULL) {
2866
      TC_MUTEX_UNLOCK(mutex_up);
2867
      rv = 0;
2868
    }
2869
    else if (g_received_close_pdu == 0) {
2870
      TC_MUTEX_UNLOCK(mutex_up);
2871
      TC_MUTEX_LOCK(mutex_train);
2872
      if (g_sound_ready_to_train > 0 && g_trained < 1 && g_sound_ready_to_send < 1) {
2873
        g_sound_ready_to_train = 0;
2874
        trainAudio();
2875
        g_trained = 1;
2876
	TC_MUTEX_UNLOCK(mutex_train);
2877
	idle_count = 0;
2878
	if (packet != NULL) {
2879
	  if (packet->s[0] != NULL) {
2880
	    g_free(packet->s[0]);
2881
	    packet->s[0] = NULL;
2882
	  }
2883
	  if (packet->s[1] != NULL) {
2884
	    g_free(packet->s[1]);
2885
	    packet->s[1] = NULL;
2886
	  }
2887
	  g_free(packet);
2888
	  packet = NULL;
2889
	}
2890
	TC_MUTEX_LOCK(mutex_close);
2891
	done = g_received_close_pdu;
2892
	TC_MUTEX_UNLOCK(mutex_close);
2893
	continue;
2894
      }
2895
      TC_MUTEX_LOCK(mutex_send);
2896
      if (g_sound_ready_to_send > 0 && packet != NULL) {
2897
	TC_MUTEX_UNLOCK(mutex_send);
2898
	TC_MUTEX_UNLOCK(mutex_train);
2899
	ls = (packet != NULL) ? packet->s[0] : NULL;
2900
	ms = (packet != NULL) ? packet->s[1] : NULL;
2901
	if (verbose) {
2902
	  MDBGLOG("sound","DEBUG\t[%s()]: ls = %p, ms = %p",__func__,ls,ms);
2903
	}
2904
	if (ls == NULL) {
2905
	  MDBGLOG("sound","WARNING\t[%s()]: ls is NULL",__func__);
2906
	}
2907
	else {
2908
	  int ltime = 0;
2909
	  size = (size_t)(ls->end - ls->data);
2910
	  if (size > 0 && g_received_close_pdu < 1) {
2911
	    if (ms != NULL && (ms->end - ms->data) > 0) {
2912
	      size += (ms->end - ms->data);
2913
	    }
2914
	    if (g_enable_skew_compensation > 0 && !g_thunk) {
2915
		if (g_outstanding_playtime > g_target_latency && ((g_ready_count < 2) || (g_outstanding_playtime > g_target_latency && (g_ready_playtime < g_low_latency)))) {
2916
		  unsigned char skipdelay = 0;
2917
		  unsigned int tdelay = 0;
2918
		  if (g_outstanding_playtime < g_min_latency && size > 20) {
2919
		    //tdelay = (pa_bytes_to_usec(size - 20, &sample_spec) / PA_USEC_PER_MSEC) * 4;
2920
		    tdelay = g_target_latency / 2;
2921
		  }
2922
		  else if (g_outstanding_playtime < g_lower_latency && size > 20) {
2923
		    //tdelay = (pa_bytes_to_usec(size - 20, &sample_spec) / PA_USEC_PER_MSEC) * 3;
2924
		    tdelay = g_target_latency / 3;
2925
		  }
2926
		  else if (g_outstanding_playtime < g_low_latency && size > 20) {
2927
		    //tdelay = (pa_bytes_to_usec(size - 20, &sample_spec) / PA_USEC_PER_MSEC) * 2;
2928
		    tdelay = g_target_latency / 4;
2929
		  }
2930
		  else {
2931
		    //tdelay = (pa_bytes_to_usec(size - 20, &sample_spec) / PA_USEC_PER_MSEC) * 2;
2932
		    tdelay = g_target_latency / 5;
2933
		  }
2934
		  if (skipdelay < 1) {
2935
		    TC_MUTEX_LOCK(mutex_underrun);
2936
		    g_underruns++;
2937
		    g_most_recent_underrun_timestamp = g_time2();
2938
		    TC_MUTEX_UNLOCK(mutex_underrun);
2939
		  }
2940
		  if (tdelay > 19) {
2941
		    g_sleep(tdelay);
2942
		  }
2943
		}
2944
		else if (g_underruns > 0) {
2945
		  long int tnow = g_time2();
2946
		  TC_MUTEX_LOCK(mutex_underrun);
2947
		  if (g_underruns > 0 && g_most_recent_underrun_timestamp > 0 && (tnow - g_most_recent_underrun_timestamp) > g_high_latency) {
2948
		    g_underruns = 0;
2949
		    g_most_recent_underrun_timestamp = 0;
2950
		  }
2951
		  TC_MUTEX_UNLOCK(mutex_underrun);
2952
		}
2953
	    }
2954
	    if (size > 4) {
2955
		char * datas[2] = { NULL, NULL };
2956
		size_t sizes[2] = { 0, 0 };
2957
		const unsigned int num = 2;
2958
2959
		datas[0] = ls->data;
2960
		datas[1] = ((ms->end - ms->data) > 0) ? ms->data : NULL;
2961
		sizes[0] = (ls->end - ls->data);
2962
		sizes[1] = (ms->end - ms->data);
2963
2964
		MDBGLOG("sound","DEBUG\t[%s()]: *** SENDING ls (size = %d; cBlockNo = %d)",__func__,size,packet->cBlockNo);
2965
		TC_MUTEX_LOCK(mutex_out);
2966
		send_channel_data_multiple_atomic(g_rdpsnd_chan_id, num, datas, sizes);
2967
		TC_MUTEX_UNLOCK(mutex_out);
2968
		ltime = sound_get_local_time();
2969
		TC_MUTEX_LOCK(mutex_pktlog);
2970
		if (pktlog[(packet->cBlockNo)].wOutTime == 0) { pktlog[(packet->cBlockNo)].wOutTime = ltime; }
2971
		pktlog[(packet->cBlockNo)].wTrueOutTime = ltime;
2972
		g_outstanding++;
2973
		g_outstanding_playbytes += size;
2974
		g_outstanding_playtime = (g_outstanding_playbytes > 0) ? pa_bytes_to_usec(g_outstanding_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
2975
		g_outstanding_playtime *= 1;
2976
		TC_MUTEX_UNLOCK(mutex_pktlog);
2977
	    }
2978
	    else {
2979
		MDBGLOG("sound","DEBUG\t[%s()]: *** SENDING ls (size = %d; cBlockNo = %d)",__func__,size,packet->cBlockNo);
2980
		TC_MUTEX_LOCK(mutex_out);
2981
		send_channel_data(g_rdpsnd_chan_id, ls->data, size);
2982
		TC_MUTEX_UNLOCK(mutex_out);
2983
		ltime = sound_get_local_time();
2984
		TC_MUTEX_LOCK(mutex_pktlog);
2985
		if (pktlog[(packet->cBlockNo)].wOutTime == 0) { pktlog[(packet->cBlockNo)].wOutTime = ltime; }
2986
		pktlog[(packet->cBlockNo)].wTrueOutTime = ltime;
2987
		g_outstanding++;
2988
		g_outstanding_playbytes += size;
2989
		g_outstanding_playtime = (g_outstanding_playbytes > 0) ? pa_bytes_to_usec(g_outstanding_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
2990
		g_outstanding_playtime *= 1;
2991
		TC_MUTEX_UNLOCK(mutex_pktlog);
2992
	    }
2993
	  }
2994
	}
2995
	if (ls != NULL) {
2996
	  if (ls->data != NULL) {
2997
	    g_free(ls->data);
2998
	    ls->data = NULL;
2999
	  }
3000
	  g_free(ls);
3001
	  ls = NULL;
3002
	}
3003
	if (ms != NULL) {
3004
	  if (ms->data != NULL) {
3005
	    g_free(ms->data);
3006
	    ms->data = NULL;
3007
	  }
3008
	  g_free(ms);
3009
	  ms = NULL;
3010
	}
3011
	if (packet != NULL && plock > 0) {
3012
	  if (packet->s[0] != NULL) {
3013
	    packet->s[0] = NULL;
3014
	  }
3015
	  if (packet->s[1] != NULL) {
3016
	    packet->s[1] = NULL;
3017
	  }
3018
	  if (plock > 0) {
3019
	    TC_MUTEX_UNLOCK(&(packet->lock));
3020
	  }
3021
	  TC_MUTEX_DEINIT(&(packet->lock));
3022
	  g_free(packet);
3023
	  packet = (pkt *)NULL;
3024
	}
3025
      }
3026
      else {
3027
        if (g_trained == 0) {
3028
	  g_sound_ready_to_train = 1;
3029
        }
3030
        TC_MUTEX_UNLOCK(mutex_send);
3031
        TC_MUTEX_UNLOCK(mutex_train);
3032
      }
3033
      rv = 0;
3034
    }
3035
3036
3037
    if (ls != NULL) {
3038
      free_stream(ls);
3039
      ls = NULL;
3040
    }
3041
    if (ms != NULL) {
3042
      free_stream(ms);
3043
      ms = NULL;
3044
    }
3045
    if (packet != NULL && plock > 0) {
3046
      if (packet->s[0] != NULL) {
3047
        packet->s[0] = NULL;
3048
      }
3049
      if (packet->s[1] != NULL) {
3050
        packet->s[1] = NULL;
3051
      }
3052
      if (plock > 0) {
3053
        TC_MUTEX_UNLOCK(&(packet->lock));
3054
      }
3055
      TC_MUTEX_DEINIT(&(packet->lock));
3056
      g_free(packet);
3057
      packet = (pkt *)NULL;
3058
    }
3059
3060
    TC_MUTEX_LOCK(mutex_close);
3061
    done = g_received_close_pdu;
3062
    TC_MUTEX_UNLOCK(mutex_close);
3063
  }
3064
3065
 exit:;
3066
  if (verbose) {
3067
    MDBGLOG("sound","INFO\t[%s()]: done. [%d, %d]",__func__,g_getpid(),g_gettid());
3068
  }
3069
  TC_THREAD_EXIT(NULL);
3070
}
3071
3072
/*****************************************************************************/
3073
void * APP_CC
3074
sound_inst(const char * cname) {
3075
  void * res = NULL;
3076
  
3077
  if (!g_strncmp(cname,"AUDIO_FORMAT",g_strlen(cname)) || !g_strncmp(cname,"WAVEFORMATEX",g_strlen(cname))) {
3078
    res = (void *)g_malloc(sizeof(AUDIO_FORMAT),1);
3079
    /* ((AUDIO_FORMAT *)res)->__destructor = &destroy_AUDIO_FORMAT; */
3080
    construct_AUDIO_FORMAT(res);
3081
  }
3082
  else if (!g_strncmp(cname,"SNDTRAINING",g_strlen(cname))) {
3083
    res = (void *)g_malloc(sizeof(SNDTRAINING),1);
3084
    ((SNDTRAINING *)res)->__destructor = &destroy_SNDTRAINING;
3085
    construct_SNDTRAINING(res);
3086
  }
3087
  else if (!g_strncmp(cname,"SNDCLOSE",g_strlen(cname))) {
3088
    res = (void *)g_malloc(sizeof(SNDCLOSE),1);
3089
    ((SNDCLOSE *)res)->__destructor = &destroy_SNDCLOSE;
3090
  }
3091
  else if (!g_strncmp(cname,"SNDWAV",g_strlen(cname))) {
3092
    res = (void *)g_malloc(sizeof(SNDWAV),1);
3093
    ((SNDWAV *)res)->__destructor = &destroy_SNDWAV;
3094
  }
3095
  else if (!g_strncmp(cname,"SNDWAVINFO",g_strlen(cname))) {
3096
    res = (void *)g_malloc(sizeof(SNDWAVINFO),1);
3097
    ((SNDWAVINFO *)res)->__destructor = &destroy_SNDWAVINFO;
3098
  }
3099
  else if (!g_strncmp(cname,"SNDWAV_CONFIRM",g_strlen(cname))) {
3100
    res = (void *)g_malloc(sizeof(SNDWAV_CONFIRM),1);
3101
    ((SNDWAV_CONFIRM *)res)->__destructor = &destroy_SNDWAV_CONFIRM;
3102
    construct_SNDWAV_CONFIRM((SNDWAV_CONFIRM *)res);
3103
  }
3104
  else if (!g_strncmp(cname,"SNDTRAININGCONFIRM",g_strlen(cname))) {
3105
    res = (void *)g_malloc(sizeof(SNDTRAININGCONFIRM),1);
3106
    ((SNDTRAININGCONFIRM *)res)->__destructor = &destroy_SNDTRAININGCONFIRM;
3107
    construct_SNDTRAININGCONFIRM((SNDTRAININGCONFIRM *)res);
3108
  }
3109
  else if (!g_strncmp(cname,"CLIENT_AUDIO_VERSION_AND_FORMATS",g_strlen(cname))) {
3110
    res = (void *)g_malloc(sizeof(CLIENT_AUDIO_VERSION_AND_FORMATS),1);
3111
    ((CLIENT_AUDIO_VERSION_AND_FORMATS *)res)->__destructor = &destroy_CLIENT_AUDIO_VERSION_AND_FORMATS;
3112
    construct_CLIENT_AUDIO_VERSION_AND_FORMATS(res);
3113
  }
3114
  else if (!g_strncmp(cname,"SERVER_AUDIO_VERSION_AND_FORMATS",g_strlen(cname))) {
3115
    res = (void *)g_malloc(sizeof(SERVER_AUDIO_VERSION_AND_FORMATS),1);
3116
    ((SERVER_AUDIO_VERSION_AND_FORMATS *)res)->__destructor = &destroy_SERVER_AUDIO_VERSION_AND_FORMATS;    
3117
  }
3118
  else if (!g_strncmp(cname,"QUALITY_MODE",g_strlen(cname))) {
3119
    res = (void *)g_malloc(sizeof(QUALITY_MODE),1);
3120
    ((QUALITY_MODE *)res)->__destructor = &destroy_QUALITY_MODE;    
3121
    construct_QUALITY_MODE(res);
3122
  }
3123
  else if (!g_strncmp(cname,"pktq",g_strlen(cname))) {
3124
    res = (void *)g_malloc(sizeof(pktq),1);
3125
    ((pktq *)res)->__destructor = &destroy_pktq;
3126
    construct_pktq(res);
3127
  }
3128
  return res;
3129
}
3130
3131
3132
/*****************************************************************************/
3133
static size_t APP_CC
3134
sound_queue_packet(void * data, size_t len) {
3135
  size_t rv = 0;
3136
  struct stream * ls = (struct stream *)NULL;
3137
  struct stream * ms = (struct stream *)NULL;
3138
  SNDWAVINFO * pdu = (SNDWAVINFO *)NULL;
3139
  int chunk_size = 0;
3140
  unsigned char bad = 0;
3141
  double dur = 0.;
3142
  WORD bno = 0;
3143
  BYTE buf[1] = { 1 };
3144
3145
  if (g_received_close_pdu > 0) {
3146
    goto end;
3147
  }
3148
3149
  if (data == NULL || len < 1) {
3150
    MDBGLOG("sound","WARNING\t[%s()]: data = %p; len = %d",__func__,data,len);
3151
    goto end;
3152
  }
3153
3154
  TC_MUTEX_LOCK(mutex_pktq);
3155
  if (g_pktq == NULL) {
3156
    TC_MUTEX_UNLOCK(mutex_pktq);
3157
    MDBGLOG("sound","ERROR\t[%s()]: g_pktq is NULL",__func__);
3158
    goto end;
3159
  }
3160
  else {
3161
    TC_MUTEX_UNLOCK(mutex_pktq);
3162
  }
3163
3164
  TC_MUTEX_LOCK(mutex_send);
3165
  if (g_sound_ready_to_send < 1) {
3166
    TC_MUTEX_UNLOCK(mutex_send);
3167
    goto end;
3168
  }
3169
  else {
3170
    TC_MUTEX_UNLOCK(mutex_send);
3171
  }
3172
3173
  TC_MUTEX_LOCK(mutex_close);
3174
  if (g_received_close_pdu > 0) {
3175
    TC_MUTEX_UNLOCK(mutex_close);
3176
    goto end;
3177
  }
3178
  else {
3179
    TC_MUTEX_UNLOCK(mutex_close);
3180
  }
3181
3182
  chunk_size = len;
3183
3184
  pdu = (SNDWAVINFO *)g_malloc(sizeof(SNDWAVINFO), 1);
3185
  if (pdu == NULL) {
3186
    MDBGLOG("sound","ERROR\t[%s()]: pdu is NULL",__func__);
3187
    goto end;
3188
  }
3189
  else {
3190
    pdu->__destructor = &destroy_SNDWAVINFO;
3191
  }
3192
3193
  make_stream(ls);
3194
  make_stream(ms);
3195
  if (ls == NULL || ms == NULL) {
3196
    MDBGLOG("sound","ERROR\t[%s()]: failed to create stream",__func__);
3197
    goto wrapup;
3198
  }
3199
  init_stream(ls, MAX_STREAM);
3200
  init_stream(ms, MAX_STREAM);
3201
3202
  TC_MUTEX_LOCK(mutex_formats);
3203
  construct_SNDWAVINFO(pdu,g_client_format_index,chunk_size,(BYTE *)(data));
3204
  if (pdu->alen > (MAX_PDU_LENGTH - 16)) {
3205
    pdu->alen =(MAX_PDU_LENGTH - 16);
3206
  }
3207
  if (pdu->alen > 0 && g_format_byte_rate > 0) {
3208
    dur = (0. + (pdu->alen - 4)) / (0. + g_format_byte_rate);
3209
  }
3210
  else if (g_format_byte_rate > 0) {
3211
    dur = 4. / (0. + g_format_byte_rate);
3212
  }
3213
  TC_MUTEX_UNLOCK(mutex_formats);
3214
  if ((pdu->alen + 12) > MAX_PDU_LENGTH) {
3215
    MDBGLOG("sound","ERROR\t[%s()]: !!! pdu->alen is greater than MAX_PDU_LENGTH !!!",__func__);
3216
    bad = 1;
3217
  }
3218
  else if ((pdu->appendix == NULL) || !(pdu->alen > 0)) {
3219
    MDBGLOG("sound","ERROR\t[%s()]: !!! pdu->appendix = %p, pdu->alen = %d !!!",__func__,pdu->appendix,pdu->alen);
3220
    //bad = 1;
3221
  }
3222
  if (bad) {
3223
    rv = 0;
3224
    goto wrapup;
3225
  }
3226
  else {
3227
    TC_MUTEX_LOCK(mutex_block);
3228
    pdu->cBlockNo = g_current_block++;
3229
    TC_MUTEX_UNLOCK(mutex_block);
3230
    bno = pdu->cBlockNo;
3231
    sound_SNDWAVINFO_out(ls, pdu);
3232
    s_mark_end(ls);
3233
    if (pdu->alen > 4) {
3234
      sound_SNDWAV_out(ms, pdu->appendix, pdu->alen);
3235
      s_mark_end(ms);
3236
    }
3237
    else {
3238
      free_stream(ms);
3239
      ms = (struct stream *)NULL;
3240
    }
3241
  }
3242
3243
  TC_MUTEX_LOCK(mutex_pktq);
3244
  if (g_pktq != NULL && g_pktq->enq != NULL && chunk_size > 0 && pdu != NULL && pdu->alen > 4 && ls != NULL && ms != NULL && pdu->cBlockNo > -1 && pdu->cBlockNo < MAX_PKTLOG) {
3245
    pkt * tpkt = (pkt *)NULL;
3246
    tpkt = (pkt *)g_malloc(sizeof(pkt),1);
3247
    TC_MUTEX_INIT(&(tpkt->lock),g_attr);
3248
    TC_MUTEX_LOCK(&(tpkt->lock));
3249
    tpkt->magic = PKT_MAGIC;
3250
    tpkt->s[0] = ls;
3251
    tpkt->s[1] = ms;
3252
    tpkt->byteCount = pdu->alen;
3253
    tpkt->duration = dur;
3254
    tpkt->cBlockNo = bno;
3255
    tpkt->next = NULL;
3256
    tpkt->prev = NULL;
3257
    TC_MUTEX_UNLOCK(&(tpkt->lock));
3258
    g_pktq->enq(g_pktq, tpkt);
3259
    TC_MUTEX_LOCK(mutex_pktlog);
3260
    rv = chunk_size;
3261
    //rv = pdu->alen;
3262
    g_memset(&(pktlog[(pdu->cBlockNo)]),0,sizeof(pktinfo));
3263
    pktlog[(pdu->cBlockNo)].bSize = pdu->Header.BodySize;
3264
    pktlog[(pdu->cBlockNo)].wAckTime = 0;
3265
    pktlog[(pdu->cBlockNo)].wOutTime = pdu->wTimeStamp;
3266
    pktlog[(pdu->cBlockNo)].dwLength = rv;
3267
    TC_MUTEX_UNLOCK(mutex_pktlog);
3268
    ls = NULL;
3269
    ms = NULL;
3270
    tpkt = NULL;
3271
    if (tpkt != NULL) {
3272
      g_free(tpkt);
3273
      tpkt = NULL;
3274
    }
3275
  }
3276
  TC_MUTEX_UNLOCK(mutex_pktq);
3277
3278
 wrapup:;
3279
  if (ls != NULL) {
3280
    if (ls->data != NULL) {
3281
      g_free(ls->data);
3282
      ls->data = NULL;
3283
    }
3284
    g_free(ls);
3285
    ls = NULL;
3286
  }
3287
  if (ms != NULL) {
3288
    if (ms->data != NULL) {
3289
      g_free(ms->data);
3290
      ms->data = NULL;
3291
    }
3292
    g_free(ms);
3293
    ms = NULL;
3294
  }
3295
  if (pdu != NULL) {
3296
    if (0 && pdu->__destructor != NULL) {
3297
      pdu->__destructor(pdu);
3298
      pdu = NULL;
3299
    }
3300
    else {
3301
      if (pdu->appendix != NULL) {
3302
	if (0 && pdu->appendix->__destructor != NULL) {
3303
	  pdu->appendix->__destructor(pdu->appendix);
3304
	}
3305
	else {
3306
	  g_free(pdu->appendix);
3307
	}
3308
	pdu->appendix = NULL;
3309
      }
3310
      g_free(pdu);
3311
      pdu = NULL;
3312
    }
3313
  }
3314
3315
 end:;
3316
  return rv;
3317
}
3318
3319
3320
/*****************************************************************************/
3321
static int APP_CC
3322
sound_estimate_latency(void) {
3323
  int rv = 0;
3324
  int idx = 0;
3325
  int lmt = MAX_PKTLOG;
3326
  int count = 0;
3327
  long total = 0;
3328
3329
  TC_MUTEX_LOCK(mutex_pktlog);
3330
  TC_MUTEX_LOCK(mutex_formats);
3331
  for (idx = 0; idx < lmt; idx++) {
3332
    if ((pktlog[idx].wOutTime != 0) && (pktlog[idx].wAckTime != 0)) {
3333
      if (pktlog[idx].wAckTime > pktlog[idx].wOutTime) {
3334
	//total += (pktlog[idx].wAckTime - pktlog[idx].wOutTime) / pktlog[idx].bSize;
3335
	total += ((pktlog[idx].wAckTime - pktlog[idx].wOutTime) - (g_format_byte_rate / pktlog[idx].bSize)) / pktlog[idx].bSize;
3336
      }
3337
      else {
3338
	total += ((pktlog[idx].wAckTime + (65536 - pktlog[idx].wOutTime)) - (g_format_byte_rate / pktlog[idx].bSize)) / pktlog[idx].bSize;
3339
      }
3340
      count++;
3341
    }
3342
  }
3343
  TC_MUTEX_UNLOCK(mutex_formats);
3344
  TC_MUTEX_UNLOCK(mutex_pktlog);
3345
  if (count > 0) {
3346
    if (total == 0) {
3347
      rv = 0;
3348
    }
3349
    else {
3350
      rv = total / count;
3351
    }
3352
  }
3353
3354
  MDBGLOG("sound"," ** [sound_estimate_latency()] total = %ld; count = %d; rv = %d\0",total,count,rv);
3355
3356
  return rv;
3357
}
3358
3359
/*****************************************************************************
3360
 *
3361
 *	Must be called only while the caller holds "self->lock" mutex;
3362
 *	"itm" must already be fully initialized (including "itm->lock" mutex).
3363
 */
3364
static int APP_CC
3365
q_enq(pktq * self, pkt * in_itm) {
3366
  int rv = 0;
3367
  int cnt = 0;
3368
  pkt * itm = (pkt *)NULL;
3369
  assert(self);
3370
  assert(in_itm);
3371
  assert(in_itm->magic == PKT_MAGIC);
3372
  if (self->count == self->max) {
3373
    MDBGLOG("sound","ERROR\t[%s()]: <<< queue is full >>>",__func__);
3374
    rv = -1;
3375
      TC_MUTEX_UNLOCK(mutex_pktq);
3376
      if (g_idle > 0 && cond_ready != NULL && g_ready_waiting > 0) {
3377
	TC_MUTEX_LOCK(mutex_ready);
3378
	g_ready_triggered = 1;
3379
	MDBGLOG("sound","DEBUG\t[%s()]: <<< SIGNALING cond_ready >>>",__func__);
3380
	if (g_ready_waiting > 0) {
3381
	  TC_COND_BROADCAST(cond_ready);
3382
	}
3383
	else {
3384
	  TC_COND_SIGNAL(cond_ready);
3385
	}
3386
	TC_MUTEX_UNLOCK(mutex_ready);
3387
      }
3388
      else {
3389
	reset_pktq(g_pktq);
3390
      }
3391
    goto end;
3392
  }
3393
  TC_MUTEX_LOCK(&(in_itm->lock));
3394
  itm = in_itm;
3395
  if (self->top > self->bottom) {
3396
    cnt = (self->top - self->bottom) + 1;
3397
    if (cnt < self->max) {
3398
      if (self->top < (self->max - 1)) {
3399
	self->top++;
3400
      }
3401
      else {
3402
	self->top = 0;
3403
      }
3404
      if (self->items[self->top] == NULL) {
3405
	self->items[self->top] = itm;
3406
      }
3407
      else {
3408
	rv = -2;
3409
      }
3410
    }
3411
    else {
3412
      rv = -1;
3413
    }
3414
  }
3415
  else if (self->top == self->bottom) {
3416
    if (self->items[self->top] == NULL) {
3417
      self->items[self->top] = itm;
3418
    }
3419
    else {
3420
      if (self->top < (self->max - 1)) {
3421
	self->top++;
3422
      }
3423
      else {
3424
	self->top = 0;
3425
      }
3426
      if (self->items[self->top] == NULL) {
3427
	self->items[self->top] = itm;
3428
      }
3429
      else {
3430
	rv = -5;
3431
      }
3432
    }
3433
  }
3434
  else {
3435
    cnt = (self->top + 1) + (self->max - self->bottom);
3436
    if (cnt < self->max) {
3437
      if (self->top < (self->max - 1)) {
3438
	self->top++;
3439
      }
3440
      else {
3441
	self->top = 0;
3442
      }
3443
      if (self->items[self->top] == NULL) {
3444
	self->items[self->top] = itm;
3445
      }
3446
      else {
3447
	rv = -6;
3448
      }
3449
    }
3450
    else {
3451
      rv = -3;
3452
    }
3453
  }
3454
  TC_MUTEX_UNLOCK(&(itm->lock));
3455
  self->count++;
3456
 end:;
3457
  return rv;
3458
}
3459
3460
/*****************************************************************************/
3461
static pkt * APP_CC
3462
q_deq(pktq * self) {
3463
  pkt * rv = (pkt *)NULL;
3464
  if (self->top != self->bottom) {
3465
    rv = self->items[self->bottom];
3466
    self->items[self->bottom] = (pkt *)NULL;
3467
    if (self->bottom < (MAX_PKTQ - 1)) {
3468
      self->bottom++;
3469
    }
3470
    else {
3471
      self->bottom = 0;
3472
    }
3473
  }
3474
  else if (self->items[self->bottom] != NULL) {
3475
    rv = self->items[self->bottom];
3476
    self->items[self->bottom] = (pkt *)NULL;
3477
  }
3478
  self->count--;
3479
  return rv;
3480
}
3481
3482
/*****************************************************************************/
3483
static int APP_CC
3484
q_getCount(pktq * self) {
3485
  int rv = 0;
3486
  if (g_pktq != NULL) {
3487
    rv = g_pktq->count;
3488
  }
3489
  return rv;
3490
}
3491
3492
/*****************************************************************************/
3493
static int APP_CC
3494
q_getCount_old(pktq * self) {
3495
  int rv = 0;
3496
3497
  //TC_MUTEX_LOCK(mutex_sound);
3498
3499
  if (self->top > self->bottom) {
3500
    rv = (self->top - self->bottom) + 1;
3501
  }
3502
  else if (self->top == self->bottom) {
3503
    if (self->items[self->top] != NULL) {
3504
      rv = 1;
3505
    }
3506
  }
3507
  else {
3508
    rv = (self->top + 1) + (MAX_PKTQ - self->bottom);
3509
  }
3510
3511
  //TC_MUTEX_UNLOCK(mutex_sound);
3512
  return rv;
3513
}
3514
3515
/*****************************************************************************/
3516
static int APP_CC
3517
q_getMax(pktq * self) {
3518
  int rv = 0;
3519
3520
  rv = self->max;
3521
3522
  return rv;
3523
}
3524
3525
/*****************************************************************************/
3526
static int APP_CC
3527
q_setMax(pktq * self, int ival) {
3528
  int rv = 0;
3529
3530
  //TC_MUTEX_LOCK(mutex_sound);
3531
3532
  if ((ival < (MAX_PKTQ + 1)) && (ival > -1)) {
3533
    self->max = ival;
3534
  }
3535
  else {
3536
    rv = -1;
3537
  }
3538
3539
  //TC_MUTEX_UNLOCK(mutex_sound);
3540
3541
  return rv;
3542
}
3543
3544
/*****************************************************************************/
3545
static int APP_CC
3546
q_getMin(pktq * self) {
3547
  int rv = 0;
3548
3549
  rv = self->min;
3550
3551
  return rv;
3552
}
3553
3554
/*****************************************************************************/
3555
static int APP_CC
3556
q_setMin(pktq * self, int ival) {
3557
  int rv = 0;
3558
3559
  if ((ival < (MAX_PKTQ + 1)) && (ival > -1) && (ival <= self->max)) {
3560
    self->min = ival;
3561
  }
3562
  else {
3563
    rv = -1;
3564
  }
3565
3566
  return rv;
3567
}
3568
3569
/*****************************************************************************/
3570
static unsigned int APP_CC
3571
q_ready(pktq * self) {
3572
  unsigned int rv = 0;
3573
3574
  //TC_MUTEX_LOCK(mutex_sound);
3575
3576
  if (self->getCount(self) > self->min) {
3577
    rv = 1;
3578
  }
3579
3580
  //TC_MUTEX_UNLOCK(mutex_sound);
3581
  return rv;
3582
}
3583
3584
/*****************************************************************************/
3585
static void APP_CC
3586
destroy_pktq(pktq * self) {
3587
3588
  //TC_MUTEX_LOCK(mutex_sound);
3589
  //g_free(self);
3590
  //TC_MUTEX_UNLOCK(mutex_sound);
3591
3592
}
3593
3594
/************************************************************************/
3595
/*	This is called whenever new data is available 		     	*/
3596
static void APP_CC stream_read_callback(pa_stream * s, size_t length, void * userdata) {
3597
  int rdy = 0;
3598
  int rdytime = 0;
3599
  size_t idx = 0;
3600
  size_t olen = 0;
3601
  size_t rsize = 0;
3602
  unsigned int lqueued = 0;
3603
  unsigned int qcnt = 0;
3604
  const void * data = (const void *)NULL;
3605
  unsigned char skip = 0;
3606
  unsigned char mlock = 0;
3607
  unsigned char peeked = 0;
3608
  unsigned char hopper_pending = 0;
3609
  unsigned char l_free_data = 0;
3610
  pa_stream_state_t ss;
3611
3612
  assert(s);
3613
  assert(length > 0);
3614
3615
  olen = length;
3616
3617
  TC_MUTEX_LOCK(mutex_event);
3618
  if (stdio_event) {
3619
    mainloop_api->io_enable(stdio_event, PA_IO_EVENT_OUTPUT);
3620
  }
3621
  TC_MUTEX_UNLOCK(mutex_event);
3622
3623
  TC_MUTEX_LOCK(mutex_stream);
3624
3625
  if (s == NULL || length < 1) {
3626
    TC_MUTEX_UNLOCK(mutex_stream);
3627
    MDBGLOG("sound","ERROR\t[%s()]: s is NULL or length is zero (s = %p, length = %d)",__func__,s,length);
3628
    goto end;
3629
  }
3630
3631
  g_memset(&ss,0,sizeof(pa_stream_state_t));
3632
  ss = pa_stream_get_state(s);
3633
  if (ss != PA_STREAM_READY) {
3634
    TC_MUTEX_UNLOCK(mutex_stream);
3635
    MDBGLOG("sound","DEBUG\t[%s()]: stream is not ready",__func__);
3636
    goto end;
3637
  }
3638
3639
  rsize = pa_stream_readable_size(s);
3640
  while (rsize > 0) {
3641
    size_t tlen = 0;
3642
    unsigned int idx = 0;
3643
    unsigned char empty = 1;
3644
3645
    peeked = 0;
3646
    length = rsize;
3647
    data = (void *)NULL;
3648
    hopper_pending = (g_hopper_length < 1) ? 0 : 1;
3649
3650
    g_memset(&ss,0,sizeof(pa_stream_state_t));
3651
    ss = pa_stream_get_state(s);
3652
    if (ss != PA_STREAM_READY) {
3653
      TC_MUTEX_UNLOCK(mutex_stream);
3654
      MDBGLOG("sound","ERROR\t[%s()]: stream is not ready",__func__);
3655
      break;
3656
    }
3657
    else if (pa_stream_peek(s, &data, &length) < 0) {
3658
	TC_MUTEX_UNLOCK(mutex_stream);
3659
	MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_peek() failed: %s", __func__, pa_strerror(pa_context_errno(context)));
3660
	pa_quit(1);
3661
	return;
3662
    }
3663
3664
    peeked = 1;
3665
    tlen = length;
3666
3667
    if (verbose) {
3668
      MDBGLOG("sound","INFO\t[%s()]: length = %d",__func__,length);
3669
    }
3670
3671
    TC_MUTEX_LOCK(mutex_up);
3672
    TC_MUTEX_LOCK(mutex_ready);
3673
    if ((g_sound_up < 1 || g_stream_ready < 1) || (g_enable_skew_compensation > 0 && (g_thunk == 0) && ((g_ready_count >= (MAX_PKTLOG / 3)) || (g_ready_playtime > g_target_latency)))) {
3674
      TC_MUTEX_UNLOCK(mutex_ready);
3675
      TC_MUTEX_UNLOCK(mutex_up);
3676
      TC_MUTEX_LOCK(mutex_pktq);
3677
      reset_pktq(g_pktq);
3678
      TC_MUTEX_UNLOCK(mutex_pktq);
3679
      goto drop;
3680
    }
3681
    else {
3682
      g_thunk = 0;
3683
      TC_MUTEX_UNLOCK(mutex_ready);
3684
      TC_MUTEX_UNLOCK(mutex_up);
3685
    }
3686
3687
    length = MIN(length, ((MAX_PDU_LENGTH - 16) - g_hopper_length));
3688
3689
    empty = 1;
3690
    if (g_drop_silence) {
3691
      if ((length % 8) == 0) {
3692
	uint64_t * tbuf = (uint64_t *)data;
3693
	for (idx = 0; idx < (length / 8); idx++) {
3694
	  if (tbuf[idx] != 0) {
3695
	    empty = 0;
3696
	    break;
3697
	  }
3698
	}
3699
      }
3700
      else if ((length % 4) == 0) {
3701
	uint32_t * tbuf = (uint32_t *)data;
3702
	for (idx = 0; idx < (length / 4); idx++) {
3703
	  if (tbuf[idx] != 0) {
3704
	    empty = 0;
3705
	    break;
3706
	  }
3707
	}
3708
      }
3709
      else if ((length % 2) == 0) {
3710
	uint16_t * tbuf = (uint16_t *)data;
3711
	for (idx = 0; idx < (length / 2); idx++) {
3712
	  if (tbuf[idx] != 0) {
3713
	    empty = 0;
3714
	    break;
3715
	  }
3716
	}
3717
      }
3718
      else {
3719
	uint8_t * tbuf = (uint8_t *)data;
3720
	for (idx = 0; idx < length; idx++) {
3721
	  if (tbuf[idx] != 0) {
3722
	    empty = 0;
3723
	    break;
3724
	  }
3725
	}
3726
      }
3727
    }
3728
3729
    if (empty > 0 && hopper_pending == 0 && length > ((MAX_PDU_LENGTH / 2) - 10)) {
3730
      if (verbose) {
3731
	MDBGLOG("sound","DEBUG\t[%s()]: ((( EMPTY )))",__func__);
3732
      }
3733
      TC_MUTEX_LOCK(mutex_pktq);
3734
      reset_pktq(g_pktq);
3735
      TC_MUTEX_UNLOCK(mutex_pktq);
3736
      goto drop;
3737
    }
3738
3739
    TC_MUTEX_LOCK(mutex_buffer);
3740
3741
    if (length <= ((MAX_PDU_LENGTH / 2) - 10)) {
3742
      if (g_hopper_length == 0) {
3743
	g_memcpy(g_hopper, data, MIN(length,MAX_STREAM));
3744
	g_hopper_length = length;
3745
	TC_MUTEX_UNLOCK(mutex_buffer);
3746
	hopper_pending = 1;
3747
	goto drop;
3748
      }
3749
      else if ((MAX_STREAM - g_hopper_length) > 0) {
3750
	g_memcpy((g_hopper + g_hopper_length), data, MIN(length,(MAX_STREAM - g_hopper_length)));
3751
	g_hopper_length += length;
3752
	length = g_hopper_length;
3753
	data = g_hopper;
3754
	if (length <= ((MAX_PDU_LENGTH / 2) - 10)) {
3755
	  TC_MUTEX_UNLOCK(mutex_buffer);
3756
	  hopper_pending = 1;
3757
	  goto drop;
3758
	}
3759
	else {
3760
	  g_hopper_length = 0;
3761
	  hopper_pending = 0;
3762
	}
3763
      }
3764
    }
3765
3766
    if (skip == 0 && data != NULL && g_sound_up > 0 && g_stream_ready > 0) {
3767
      switch (g_preferred_wave_format) {
3768
	case WAVE_FORMAT_MPEGLAYER3:
3769
	  break;
3770
	case WAVE_FORMAT_GSM610:
3771
	  break;
3772
	case WAVE_FORMAT_MSG723:
3773
	  break;
3774
	case WAVE_FORMAT_IMA_ADPCM:
3775
	  {
3776
	    uint8_t * dst = g_malloc(length, 1);
3777
	    // length = sound_convert_pcm_to_ima_adpcm(dst, length, data, length);
3778
	    data = dst;
3779
	    l_free_data = 1;
3780
	  }
3781
	  break;
3782
	case WAVE_FORMAT_ADPCM:
3783
	  break;
3784
	case WAVE_FORMAT_PCM:
3785
	default:
3786
	  break;
3787
      }
3788
      if (skip == 0) while (length > 0) {
3789
	size_t rv = 0;
3790
	if (g_preferred_wave_format == WAVE_FORMAT_PCM) {
3791
	  rv = (length % 2 == 0) ? sound_queue_packet((uint8_t*)(data+idx), MIN(length, MAX_PDU_LENGTH - 16)) : MIN(length, MAX_PDU_LENGTH - 16);
3792
	}
3793
	else if (g_preferred_wave_format == WAVE_FORMAT_IMA_ADPCM) {
3794
	  unsigned int rem = length % 4;
3795
	  if (rem > 0) {
3796
	    length += (4 - rem);
3797
	  }
3798
	  rv = sound_queue_packet((uint8_t*)(data+idx), MIN(length, MAX_PDU_LENGTH - 16));
3799
	}
3800
	else {
3801
	  rv = (length % 2 == 0) ? sound_queue_packet((uint8_t*)(data+idx), MIN(length, MAX_PDU_LENGTH - 16)) : MIN(length, MAX_PDU_LENGTH - 16);
3802
	}
3803
	idx += rv;
3804
	length -= rv;
3805
	if (rv > 0) {
3806
	  lqueued++;
3807
	}
3808
	else if (rv == 0) {
3809
	  break;
3810
	}
3811
      }
3812
    }
3813
3814
    TC_MUTEX_UNLOCK(mutex_buffer);
3815
3816
    if (lqueued > 0) {
3817
      TC_MUTEX_LOCK(mutex_ready);
3818
      g_ready_count += lqueued;
3819
      g_ready_playbytes += length;
3820
      g_ready_playtime = (g_ready_playbytes > 0) ? pa_bytes_to_usec(g_ready_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
3821
      g_ready_playtime *= 1;
3822
      TC_MUTEX_LOCK(mutex_pktq);
3823
      if (g_pktq != NULL && g_pktq->head != NULL && g_pktq->getCount != NULL) {
3824
	qcnt = g_pktq->getCount(g_pktq);
3825
      }
3826
      TC_MUTEX_UNLOCK(mutex_pktq);
3827
      if (g_idle > 0 && cond_ready != NULL && g_ready_waiting > 0 && g_ready_count > 0 && g_ready_playtime >= (g_target_latency / 2)) {
3828
	g_ready_triggered = 1;
3829
	if (g_ready_waiting > 0) {
3830
	  TC_COND_BROADCAST(cond_ready);
3831
	}
3832
	else {
3833
	  TC_COND_SIGNAL(cond_ready);
3834
	}
3835
      }
3836
      TC_MUTEX_UNLOCK(mutex_ready);
3837
    }
3838
3839
 drop:;
3840
    if (tlen > 0 && peeked > 0) {
3841
      pa_stream_drop(s);
3842
    }
3843
3844
    if (l_free_data > 0 && data != NULL && data != g_hopper) {
3845
      g_free((void *)data);
3846
    }
3847
3848
    rsize = pa_stream_readable_size(s);
3849
  }
3850
3851
 signal:;
3852
  TC_MUTEX_LOCK(mutex_drain);
3853
  if ((g_drain > 0) && (g_outstanding_playtime <= g_target_latency)) {
3854
    TC_MUTEX_LOCK(mutex_pktq);
3855
    reset_pktq(g_pktq);
3856
    TC_MUTEX_UNLOCK(mutex_pktq);
3857
    TC_COND_SIGNAL(mutex_drain);
3858
    TC_MUTEX_UNLOCK(mutex_drain);
3859
  }
3860
  else {
3861
    TC_MUTEX_UNLOCK(mutex_drain);
3862
  }
3863
3864
  TC_MUTEX_LOCK(mutex_ready);
3865
  if (g_idle > 0 && cond_ready != NULL && g_ready_waiting > 0 && g_ready_count > 0) {
3866
    g_ready_triggered = 1;
3867
    if (g_ready_waiting > 0) {
3868
      TC_COND_BROADCAST(cond_ready);
3869
    }
3870
    else {
3871
      TC_COND_SIGNAL(cond_ready);
3872
    }
3873
  }
3874
  TC_MUTEX_UNLOCK(mutex_ready);
3875
3876
 end:;
3877
  TC_MUTEX_UNLOCK(mutex_stream);
3878
  return;
3879
}
3880
3881
/*****************************************************************************/
3882
/* This routine is called whenever the sink state changes */
3883
static void APP_CC pa_sink_state_callback(struct pa_context * c, const pa_sink_info * s, void * userdata) {
3884
    const char * sname = (s->name == NULL || g_strlen(s->name) < 1) ? "" : s->name;
3885
    const char * dname = (s->driver == NULL || g_strlen(s->driver) < 1) ? "" : s->driver;
3886
    if (s == NULL) {
3887
      goto end;
3888
    }
3889
    else switch (s->state) {
3890
      case PA_SINK_RUNNING:
3891
	{
3892
	  MDBGLOG("sound","INFO\t[%s()]: PA_SINK_RUNNING (name: %s, driver: %s)", __func__, sname, dname);
3893
	  if (g_sound_up < 1) {
3894
	    TC_MUTEX_LOCK(mutex_up);
3895
	    g_sound_up = 1;
3896
	    TC_MUTEX_UNLOCK(mutex_up);
3897
	  }
3898
	}
3899
	break;
3900
      case PA_SINK_IDLE:
3901
	{
3902
	  MDBGLOG("sound","INFO\t[%s()]: PA_SINK_IDLE (name: %s, driver: %s)", __func__, sname, dname);
3903
	  if (g_sound_up < 1) {
3904
	    TC_MUTEX_LOCK(mutex_up);
3905
	    g_sound_up = 1;
3906
	    TC_MUTEX_UNLOCK(mutex_up);
3907
	  }
3908
	}
3909
	break;
3910
      case PA_SINK_SUSPENDED:
3911
	{
3912
	  MDBGLOG("sound","INFO\t[%s()]: PA_SINK_SUSPENDED (name: %s, driver: %s)", __func__, sname, dname);
3913
	  if (g_sound_up < 1) {
3914
	    TC_MUTEX_LOCK(mutex_up);
3915
	    if (g_sound_up < 1) {
3916
	      g_sound_up = 1;
3917
	    }
3918
	    TC_MUTEX_UNLOCK(mutex_up);
3919
	  }
3920
	}
3921
	break;
3922
      case PA_SINK_INVALID_STATE:
3923
      default:
3924
	{
3925
	  MDBGLOG("sound","INFO\t[%s()]: PA_SINK_INVALID_STATE (name: %s, driver: %s)", __func__, sname, dname);
3926
	  if (g_sound_up > 0) {
3927
	    TC_MUTEX_LOCK(mutex_up);
3928
	    if (g_sound_up > 0) {
3929
	      g_sound_up = 0;
3930
	    }
3931
	    TC_MUTEX_UNLOCK(mutex_up);
3932
	  }
3933
	}
3934
	break;
3935
    }
3936
  end:;
3937
    return;
3938
}
3939
3940
3941
/*****************************************************************************/
3942
/* This routine is called whenever the sink state changes */
3943
static void APP_CC pa_source_state_callback(struct pa_context * c, const pa_source_info * s, void * userdata) {
3944
    const char * sname = (s->name == NULL || g_strlen(s->name) < 1) ? "" : s->name;
3945
    const char * dname = (s->driver == NULL || g_strlen(s->driver) < 1) ? "" : s->driver;
3946
    if (s == NULL) {
3947
      goto end;
3948
    }
3949
    else switch (s->state) {
3950
      case PA_SOURCE_RUNNING:
3951
	{
3952
	  MDBGLOG("sound","INFO\t[%s()]: PA_SOURCE_RUNNING (name: %s, driver: %s)", __func__, sname, dname);
3953
	  if (g_sound_up < 1) {
3954
	    TC_MUTEX_LOCK(mutex_up);
3955
	    g_sound_up = 1;
3956
	    TC_MUTEX_UNLOCK(mutex_up);
3957
	  }
3958
	}
3959
	break;
3960
      case PA_SOURCE_IDLE:
3961
	{
3962
	  MDBGLOG("sound","INFO\t[%s()]: PA_SOURCE_IDLE (name: %s, driver: %s)", __func__, sname, dname);
3963
	  if (g_sound_up < 1) {
3964
	    TC_MUTEX_LOCK(mutex_up);
3965
	    g_sound_up = 1;
3966
	    TC_MUTEX_UNLOCK(mutex_up);
3967
	  }
3968
	}
3969
	break;
3970
      case PA_SOURCE_SUSPENDED:
3971
	{
3972
	  MDBGLOG("sound","INFO\t[%s()]: PA_SOURCE_SUSPENDED (name: %s, driver: %s)", __func__, sname, dname);
3973
	  if (g_sound_up < 1) {
3974
	    TC_MUTEX_LOCK(mutex_up);
3975
	    if (g_sound_up < 1) {
3976
	      g_sound_up = 1;
3977
	    }
3978
	    TC_MUTEX_UNLOCK(mutex_up);
3979
	  }
3980
	}
3981
	break;
3982
      case PA_SOURCE_INVALID_STATE:
3983
      default:
3984
	{
3985
	  MDBGLOG("sound","INFO\t[%s()]: PA_SOURCE_INVALID_STATE (name: %s, driver: %s)", __func__, sname, dname);
3986
	  if (g_sound_up > 0) {
3987
	    TC_MUTEX_LOCK(mutex_up);
3988
	    if (g_sound_up > 0) {
3989
	      g_sound_up = 0;
3990
	    }
3991
	    TC_MUTEX_UNLOCK(mutex_up);
3992
	  }
3993
	}
3994
	break;
3995
    }
3996
  end:;
3997
    return;
3998
}
3999
4000
4001
/*****************************************************************************/
4002
/* This routine is called whenever the stream state changes */
4003
static void APP_CC stream_state_callback(pa_stream * s, void * userdata) {
4004
    int sstate = 0;
4005
    unsigned char mlock = 0;
4006
    pa_stream_state_t state;
4007
    const pa_sample_spec * ss = (const pa_sample_spec *)NULL;
4008
4009
    assert(s);
4010
4011
    g_memset(&state,0,sizeof(pa_stream_state_t));
4012
4013
    if (verbose) {
4014
      MDBGLOG("sound","INFO\t[%s()]: called (s = %p)",__func__,s);
4015
    }
4016
4017
    TC_MUTEX_LOCK(mutex_stream);
4018
4019
    state = pa_stream_get_state(s);
4020
4021
    switch (state) {
4022
        case PA_STREAM_CREATING:
4023
	  {
4024
		if (verbose) {
4025
		  MDBGLOG("sound", "INFO\t[%s()]: PA_STREAM_CREATING", __func__);
4026
		}
4027
	  }
4028
	  break;
4029
        case PA_STREAM_TERMINATED:
4030
	  {
4031
		if (verbose) {
4032
		  MDBGLOG("sound", "INFO\t[%s()]: PA_STREAM_TERMINATED", __func__);
4033
		}
4034
	  }
4035
	  break;
4036
4037
        case PA_STREAM_READY:
4038
          {
4039
                char cmt[PA_CHANNEL_MAP_SNPRINT_MAX], sst[PA_SAMPLE_SPEC_SNPRINT_MAX];
4040
                const pa_buffer_attr * a = (const pa_buffer_attr *)NULL;
4041
		if (verbose) {
4042
		  MDBGLOG("sound", "INFO\t[%s()]: PA_STREAM_READY (Stream successfully created).", __func__);
4043
		}
4044
		if (!(a = pa_stream_get_buffer_attr(s))) {
4045
		  MDBGLOG("sound", "INFO\t[%s()]: pa_stream_get_buffer_attr() failed (\"%s\")", __func__, pa_strerror(pa_context_errno(pa_stream_get_context(s))));
4046
		}
4047
                else {
4048
		    ss = pa_stream_get_sample_spec(s);
4049
                    if (verbose > 0 && mode == PLAYBACK) {
4050
                        MDBGLOG("sound", "INFO\t[%s()]: Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u", __func__, a->maxlength, a->tlength, a->prebuf, a->minreq);
4051
		    }
4052
                    else if (verbose > 0) {
4053
                        assert(mode == RECORD);
4054
                        MDBGLOG("sound", "INFO\t[%s()]: Buffer metrics: maxlength=%u, fragsize=%u", __func__, a->maxlength, a->fragsize);
4055
                    }
4056
                }
4057
		if (verbose) {
4058
                  MDBGLOG("sound", "INFO\t[%s()]: Using sample spec '%s', channel map '%s'.", __func__,
4059
                        pa_sample_spec_snprint(sst, sizeof(sst), pa_stream_get_sample_spec(s)),
4060
                        pa_channel_map_snprint(cmt, sizeof(cmt), pa_stream_get_channel_map(s)));
4061
                  MDBGLOG("sound", "INFO\t[%s()]: Connected to device %s (%u, %ssuspended).",
4062
			__func__,
4063
                        pa_stream_get_device_name(s),
4064
                        pa_stream_get_device_index(s),
4065
                        pa_stream_is_suspended(s) ? "" : "not ");
4066
		}
4067
          }
4068
	  break;
4069
        case PA_STREAM_FAILED:
4070
        default:
4071
	    {
4072
		MDBGLOG("sound", "INFO\t[%s()]: Stream error: %s", __func__, pa_strerror(pa_context_errno(pa_stream_get_context(s))));
4073
		if (mutex_stream_ready != NULL) {
4074
		  TC_MUTEX_LOCK(mutex_stream_ready);
4075
		  g_stream_ready = 0;
4076
		  TC_MUTEX_UNLOCK(mutex_stream_ready);
4077
		}
4078
		pa_quit(1);
4079
		goto end;
4080
	    }
4081
    }
4082
4083
    if (state == PA_STREAM_READY) {
4084
      unsigned char plock = 0;
4085
      pa_operation * op = (pa_operation *)NULL;
4086
      if (mutex_up != NULL) {
4087
	TC_MUTEX_LOCK(mutex_up);
4088
	if (g_sound_up < 1) {
4089
	  g_sound_up = 1;
4090
	}
4091
	TC_MUTEX_UNLOCK(mutex_up);
4092
      }
4093
      if (mutex_stream_ready != NULL && cond_stream_ready != NULL) {
4094
	TC_MUTEX_LOCK(mutex_stream_ready);
4095
	if (g_stream_ready < 1) {
4096
	  g_stream_ready = 1;
4097
	  TC_COND_SIGNAL(cond_stream_ready);
4098
	}
4099
	TC_MUTEX_UNLOCK(mutex_stream_ready);
4100
      }
4101
      if (!pa_threaded_mainloop_in_thread(mt)) {
4102
	pa_threaded_mainloop_lock(mt);
4103
	plock = 1;
4104
      }
4105
      if (!(op = pa_stream_flush(s, NULL, NULL))) {
4106
	MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_flush() -> \"%s\"", __func__, pa_strerror(pa_context_errno(context)));
4107
	if (plock > 0) {
4108
	  pa_threaded_mainloop_unlock(mt);
4109
	  plock = 0;
4110
	}
4111
      }
4112
      TC_MUTEX_LOCK(mutex_pktq);
4113
      reset_pktq(g_pktq);
4114
      TC_MUTEX_UNLOCK(mutex_pktq);
4115
      if (op != NULL) {
4116
	pa_operation_unref(op);
4117
	op = NULL;
4118
      }
4119
      if (pa_stream_is_corked(s) && !(op = pa_stream_cork(s, 0, NULL, NULL))) {
4120
	MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_cork() -> \"%s\"", __func__, pa_strerror(pa_context_errno(context)));
4121
	if (plock > 0) {
4122
	  pa_threaded_mainloop_unlock(mt);
4123
	  plock = 0;
4124
	}
4125
	TC_MUTEX_UNLOCK(mutex_stream);
4126
	pa_quit(1);
4127
	return;
4128
      }
4129
      if (op != NULL) {
4130
	pa_operation_unref(op);
4131
	op = NULL;
4132
      }
4133
      if (plock > 0) {
4134
	pa_threaded_mainloop_unlock(mt);
4135
	plock = 0;
4136
      }
4137
    }
4138
    else {
4139
      unsigned char plock = 0;
4140
      pa_operation * op = (pa_operation *)NULL;
4141
      if (!pa_stream_is_corked(s) && !(op = pa_stream_cork(s, 1, NULL, NULL))) {
4142
	MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_cork() -> \"%s\"", __func__, pa_strerror(pa_context_errno(context)));
4143
	if (plock > 0) {
4144
	  pa_threaded_mainloop_unlock(mt);
4145
	  plock = 0;
4146
	}
4147
	TC_MUTEX_UNLOCK(mutex_stream);
4148
	pa_quit(1);
4149
	return;
4150
      }
4151
      if (op != NULL) {
4152
	pa_operation_unref(op);
4153
	op = NULL;
4154
      }
4155
      if (mutex_up != NULL) {
4156
	TC_MUTEX_LOCK(mutex_up);
4157
	if (g_sound_up > 0) {
4158
	  g_sound_up = 0;
4159
	  start_drain_noquit();
4160
	}
4161
	TC_MUTEX_UNLOCK(mutex_up);
4162
      }
4163
      TC_MUTEX_LOCK(mutex_stream_ready);
4164
      g_stream_ready = 0;
4165
      TC_MUTEX_UNLOCK(mutex_stream_ready);
4166
      if (!pa_threaded_mainloop_in_thread(mt)) {
4167
	pa_threaded_mainloop_lock(mt);
4168
	plock = 1;
4169
      }
4170
      if (g_sound_up > 0 && !(op = pa_stream_flush(s, NULL, NULL))) {
4171
	MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_flush() -> \"%s\"", __func__, pa_strerror(pa_context_errno(context)));
4172
	if (plock > 0) {
4173
	  pa_threaded_mainloop_unlock(mt);
4174
	  plock = 0;
4175
	}
4176
	TC_MUTEX_UNLOCK(mutex_stream);
4177
	pa_quit(1);
4178
	return;
4179
      }
4180
      TC_MUTEX_LOCK(mutex_pktq);
4181
      reset_pktq(g_pktq);
4182
      TC_MUTEX_UNLOCK(mutex_pktq);
4183
      if (op != NULL) {
4184
	pa_operation_unref(op);
4185
	op = NULL;
4186
      }
4187
      if (plock > 0) {
4188
	pa_threaded_mainloop_unlock(mt);
4189
	plock = 0;
4190
      }
4191
    }
4192
4193
  end:;
4194
    TC_MUTEX_UNLOCK(mutex_stream);
4195
    return;
4196
}
4197
4198
/*****************************************************************************/
4199
static void APP_CC stream_event_callback(pa_stream * s, const char * name, pa_proplist * pl, void * userdata) {
4200
    char * t = (char *)NULL;
4201
4202
    TC_MUTEX_LOCK(mutex_stream);
4203
4204
    assert(s);
4205
    assert(name);
4206
    assert(pl);
4207
4208
    t = pa_proplist_to_string_sep(pl, ", ");
4209
    MDBGLOG("sound", "INFO\t[%s()]: Got event '%s', properties '%s'", __func__, name, t);
4210
    pa_xfree(t);
4211
4212
    TC_MUTEX_UNLOCK(mutex_stream);
4213
}
4214
4215
/*****************************************************************************/
4216
static void APP_CC stream_started_callback(pa_stream * s, void * userdata) {
4217
4218
    TC_MUTEX_LOCK(mutex_stream);
4219
4220
    assert(s);
4221
4222
    //if (verbose) {
4223
        MDBGLOG("sound", "INFO\t[%s()]: Stream started.", __func__);
4224
    //}
4225
4226
    TC_MUTEX_UNLOCK(mutex_stream);
4227
}
4228
4229
/*****************************************************************************/
4230
static void APP_CC stream_moved_callback(pa_stream * s, void * userdata) {
4231
    TC_MUTEX_LOCK(mutex_stream);
4232
4233
    assert(s);
4234
4235
    //if (verbose) {
4236
        MDBGLOG("sound", "INFO\t[%s()]: Stream moved to device %s (%u, %ssuspended).", __func__, pa_stream_get_device_name(s), pa_stream_get_device_index(s), ((pa_stream_is_suspended(s)) ? "" : "INFO\t[%s()]: not "));
4237
    //}
4238
4239
    TC_MUTEX_UNLOCK(mutex_stream);
4240
}
4241
4242
4243
/*****************************************************************************/
4244
/*	This is called whenever the context status changes		     */
4245
static void APP_CC context_state_callback(pa_context * c, void * userdata) {
4246
    assert(c);
4247
4248
    if (verbose) {
4249
      MDBGLOG("sound","INFO\t[%s()]: ",__func__);
4250
    }
4251
4252
    switch (pa_context_get_state(c)) {
4253
        case PA_CONTEXT_CONNECTING:
4254
        case PA_CONTEXT_AUTHORIZING:
4255
        case PA_CONTEXT_SETTING_NAME:
4256
            break;
4257
4258
        case PA_CONTEXT_READY: {
4259
            int r = 0;
4260
            pa_buffer_attr buffer_attr;
4261
4262
	    TC_MUTEX_LOCK(mutex_stream);
4263
4264
            assert(c);
4265
            assert(!stream);
4266
4267
	    if (verbose) {
4268
		MDBGLOG("sound", "INFO\t[%s()]: Connection established.", __func__);
4269
	    }
4270
4271
	    stream_name = g_strdup("xrdp_sink");
4272
	    if (!(stream = pa_stream_new(c, stream_name, &sample_spec, ((channel_map_set) ? &channel_map : NULL)))) {
4273
		TC_MUTEX_UNLOCK(mutex_stream);
4274
		MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_new() failed: %s", __func__, pa_strerror(pa_context_errno(c)));
4275
		goto fail;
4276
	    }
4277
4278
	    pa_stream_set_state_callback(stream, stream_state_callback, NULL);
4279
	    pa_stream_set_read_callback(stream, stream_read_callback, NULL);
4280
	    pa_stream_set_suspended_callback(stream, stream_suspended_callback, NULL);
4281
	    pa_stream_set_moved_callback(stream, stream_moved_callback, NULL);
4282
	    pa_stream_set_underflow_callback(stream, stream_underflow_callback, NULL);
4283
	    pa_stream_set_overflow_callback(stream, stream_overflow_callback, NULL);
4284
	    pa_stream_set_started_callback(stream, stream_started_callback, NULL);
4285
	    pa_stream_set_event_callback(stream, stream_event_callback, NULL);
4286
	    pa_stream_set_buffer_attr_callback(stream, stream_buffer_attr_callback, NULL);
4287
4288
	    g_memset(&buffer_attr, 0, sizeof(buffer_attr));
4289
	    buffer_attr.tlength = (uint32_t) -1;
4290
	    buffer_attr.maxlength = (uint32_t) -1;
4291
	    buffer_attr.prebuf = (uint32_t) -1;
4292
	    buffer_attr.minreq = (uint32_t) -1;
4293
	    buffer_attr.fragsize = (uint32_t) -1;
4294
4295
	    buffer_attr.tlength = (uint32_t) 32768;
4296
	    buffer_attr.maxlength = (uint32_t) -1;
4297
	    buffer_attr.prebuf = (uint32_t) 0;
4298
	    buffer_attr.minreq = (uint32_t) -1;
4299
	    buffer_attr.fragsize = (uint32_t) -1;
4300
4301
	    pa_stream_set_latency_update_callback(stream, pa_stream_latency_update_cb, NULL);
4302
4303
	    TC_MUTEX_UNLOCK(mutex_stream);
4304
4305
	    if (mode == PLAYBACK) {
4306
		pa_cvolume cv;
4307
		if ((r = pa_stream_connect_playback(stream, device, latency > 0 ? &buffer_attr : NULL, flags | PA_STREAM_START_CORKED, volume_is_set ? pa_cvolume_set(&cv, sample_spec.channels, volume) : NULL, NULL)) < 0) {
4308
		    TC_MUTEX_UNLOCK(mutex_stream);
4309
		    MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_connect_playback() failed: %s", __func__, pa_strerror(pa_context_errno(c)));
4310
		    goto fail;
4311
		}
4312
	    }
4313
	    else {
4314
		if ((r = pa_stream_connect_record(stream, device, latency > 0 ? &buffer_attr : NULL, flags | PA_STREAM_START_CORKED)) < 0) {
4315
		    TC_MUTEX_UNLOCK(mutex_stream);
4316
		    MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_connect_record() failed: %s", __func__, pa_strerror(pa_context_errno(c)));
4317
		    goto fail;
4318
		}
4319
	    }
4320
4321
	    /* Subscribe to events */
4322
	    {
4323
	      int success = 0;
4324
	      pa_operation * o = (pa_operation *)NULL;
4325
	      if (!(o = pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK_INPUT, pa_context_success_cb, &success))) {
4326
	        MDBGLOG("source","ERROR\t[%s()]: pa_context_subscribe() failed: %s", __func__, pa_strerror(pa_context_errno(context)));
4327
	        goto fail;
4328
	      }
4329
	    }
4330
	    
4331
4332
	    TC_MUTEX_LOCK(mutex_init);
4333
	    TC_COND_BROADCAST(cond_init);
4334
	    TC_MUTEX_UNLOCK(mutex_init);
4335
4336
	    break;
4337
	}
4338
4339
        case PA_CONTEXT_TERMINATED:
4340
	    TC_MUTEX_UNLOCK(mutex_stream);
4341
	    break;
4342
4343
        case PA_CONTEXT_FAILED:
4344
        default:
4345
	    TC_MUTEX_UNLOCK(mutex_stream);
4346
            MDBGLOG("sound", "ERROR\t[%s()]: Connection failure: %s", __func__, pa_strerror(pa_context_errno(c)));
4347
	    break;
4348
    }
4349
4350
    return;
4351
4352
  fail:;
4353
    pa_quit(1);
4354
    return;
4355
}
4356
4357
static void APP_CC pa_quit(int ret) {
4358
    assert(mainloop_api);
4359
    if (verbose) {
4360
	MDBGLOG("sound","INFO\t[%s()]: quitting PulseAudio",__func__);
4361
    }
4362
    mainloop_api->quit(mainloop_api, ret);
4363
}
4364
4365
/* Connection draining complete */
4366
static void APP_CC context_drain_complete(pa_context * c, void * userdata) {
4367
    pa_context_disconnect(c);
4368
}
4369
4370
/* Stream draining complete */
4371
static void APP_CC stream_drain_complete(pa_stream * s, int success, void * userdata) {
4372
4373
    TC_MUTEX_LOCK(mutex_stream);
4374
4375
    if (!success) {
4376
        MDBGLOG("sound", "ERROR\t[%s()]: Failed to drain stream: %s", __func__, pa_strerror(pa_context_errno(context)));
4377
        pa_quit(1);
4378
    }
4379
4380
    if (verbose) {
4381
        MDBGLOG("sound", "INFO\t[%s()]: Playback stream drained.",__func__);
4382
    }
4383
4384
    TC_MUTEX_UNLOCK(mutex_stream);
4385
4386
    pa_stream_disconnect(stream);
4387
4388
    TC_MUTEX_LOCK(mutex_stream);
4389
4390
    pa_stream_unref(stream);
4391
    stream = NULL;
4392
4393
    TC_MUTEX_UNLOCK(mutex_stream);
4394
4395
    if (!pa_context_drain(context, context_drain_complete, NULL)) {
4396
        pa_context_disconnect(context);
4397
    }
4398
    else {
4399
        if (verbose) {
4400
            MDBGLOG("sound", "INFO\t[%s()]: Draining connection to server.", __func__);
4401
	}
4402
    }
4403
}
4404
4405
/* Start draining */
4406
static void APP_CC start_drain(void) {
4407
4408
    if (verbose) {
4409
      MDBGLOG("sound","INFO\t[%s()]: ",__func__);
4410
    }
4411
4412
    TC_MUTEX_LOCK(mutex_stream);
4413
4414
    if (stream) {
4415
        pa_operation * o = (pa_operation *)NULL;
4416
4417
	pa_threaded_mainloop_lock(mt);
4418
4419
        pa_stream_set_write_callback(stream, NULL, NULL);
4420
4421
        if (!(o = pa_stream_drain(stream, stream_drain_complete, NULL))) {
4422
            MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_drain() -> \"%s\"", __func__, pa_strerror(pa_context_errno(context)));
4423
	    pa_threaded_mainloop_unlock(mt);
4424
	    TC_MUTEX_UNLOCK(mutex_stream);
4425
            pa_quit(1);
4426
            return;
4427
        }
4428
4429
        pa_operation_unref(o);
4430
4431
	pa_threaded_mainloop_unlock(mt);
4432
    }
4433
    else {
4434
        pa_quit(0);
4435
    }
4436
4437
    TC_MUTEX_UNLOCK(mutex_stream);
4438
}
4439
4440
/* Start draining */
4441
static void APP_CC start_drain_noquit(void) {
4442
4443
    if (verbose) {
4444
      MDBGLOG("sound","INFO\t[%s()]: ",__func__);
4445
    }
4446
4447
    TC_MUTEX_LOCK(mutex_stream);
4448
4449
    if (stream) {
4450
        pa_operation * o = (pa_operation *)NULL;
4451
4452
        pa_stream_set_write_callback(stream, NULL, NULL);
4453
4454
        if (!(o = pa_stream_drain(stream, NULL, NULL))) {
4455
	    TC_MUTEX_UNLOCK(mutex_stream);
4456
            MDBGLOG("sound", "ERROR\t[%s()]: pa_stream_drain() -> \"%s\"", __func__, pa_strerror(pa_context_errno(context)));
4457
            pa_quit(1);
4458
            return;
4459
        }
4460
4461
        pa_operation_unref(o);
4462
    }
4463
4464
    TC_MUTEX_UNLOCK(mutex_stream);
4465
}
4466
4467
/*****************************************************************************/
4468
/* Some data may be written to STDOUT */
4469
static void APP_CC stdout_callback(pa_mainloop_api * a, pa_io_event * e, int fd, pa_io_event_flags_t f, void * userdata) {
4470
    int tcnt = 0;
4471
    int cum = 0;
4472
    int rem = 0;
4473
    int lbuf_index = 0;
4474
    int lbuf_length = 0;
4475
    int lqueued = 0;
4476
    int qcnt = 0;
4477
    uint8_t * lbuf = (uint8_t *)NULL;
4478
4479
    assert(a == mainloop_api);
4480
    assert(e);
4481
    assert(stdio_event == e);
4482
4483
    if (mainloop_api != NULL && stdio_event != NULL) {
4484
	mainloop_api->io_free(stdio_event);
4485
	stdio_event = NULL;
4486
    }
4487
4488
    return;
4489
4490
    TC_MUTEX_LOCK(mutex_buffer);
4491
4492
    if (verbose) {
4493
      MDBGLOG("sound", "INFO\t[%s()]: called (buffer = %p, buffer_index = %d, buffer_length = %d) [%d]", __func__, buffer, buffer_index, buffer_length, g_gettid());
4494
    }
4495
4496
    if (buffer == NULL) {
4497
	TC_MUTEX_LOCK(mutex_event);
4498
	mainloop_api->io_enable(stdio_event, PA_IO_EVENT_NULL);
4499
	TC_MUTEX_UNLOCK(mutex_event);
4500
	TC_MUTEX_UNLOCK(mutex_buffer);
4501
	goto end;
4502
    }
4503
4504
    lbuf = (uint8_t *)g_malloc(buffer_length, 1);
4505
    g_memcpy(lbuf, buffer, buffer_length);
4506
    lbuf_index = buffer_index;
4507
    lbuf_length = buffer_length;
4508
4509
    if (lbuf == NULL) {
4510
      TC_MUTEX_UNLOCK(mutex_buffer);
4511
      goto end;
4512
    }
4513
    else if (lbuf != NULL) {
4514
      pa_xfree(buffer);
4515
      buffer = (uint8_t *)NULL;
4516
      buffer_length = buffer_index = 0;
4517
    }
4518
4519
    TC_MUTEX_UNLOCK(mutex_buffer);
4520
4521
    while (lbuf_length > 0) {
4522
	int rv = sound_queue_packet((uint8_t*)(lbuf+lbuf_index), MINVAL(lbuf_length, MAX_PDU_LENGTH - 16));
4523
	rv = (rv < 0) ? 0 : rv;
4524
	lbuf_index += rv;
4525
	lbuf_length -= rv;
4526
	if (rv > 0) {
4527
	  lqueued++;
4528
	}
4529
    }
4530
4531
    if (lbuf != NULL) {
4532
	g_free(lbuf);
4533
    }
4534
4535
    if (lqueued > 0) {
4536
      TC_MUTEX_LOCK(mutex_ready);
4537
      g_ready_count += lqueued;
4538
      g_ready_playbytes += lbuf_length;
4539
      g_ready_playtime = (g_ready_playbytes > 0) ? pa_bytes_to_usec(g_ready_playbytes, &sample_spec) / PA_USEC_PER_MSEC : 0;
4540
      g_ready_playtime *= 1;
4541
      TC_MUTEX_UNLOCK(mutex_ready);
4542
    }
4543
4544
    TC_MUTEX_LOCK(mutex_pktq);
4545
    qcnt = g_pktq->getCount(g_pktq);
4546
    TC_MUTEX_UNLOCK(mutex_pktq);
4547
    TC_MUTEX_LOCK(mutex_ready);
4548
    if (g_idle > 0 && cond_ready != NULL && qcnt > 0 && g_ready_waiting > 0 && g_ready_count > 0) {
4549
      g_ready_triggered = 1;
4550
      if (g_ready_waiting > 0) {
4551
	TC_COND_BROADCAST(cond_ready);
4552
      }
4553
      else {
4554
	TC_COND_SIGNAL(cond_ready);
4555
      }
4556
    }
4557
    TC_MUTEX_UNLOCK(mutex_ready);
4558
4559
  end:;
4560
    if (verbose) {
4561
      MDBGLOG("sound", "INFO\t[%s()]: done. [%d]", __func__, g_gettid());
4562
    }
4563
}
4564
4565
4566
/*****************************************************************************/
4567
/* New data on STDIN  */
4568
static void APP_CC stdin_callback(pa_mainloop_api* a, pa_io_event * e, int fd, pa_io_event_flags_t f, void * userdata) {
4569
    size_t l, w = 0;
4570
    ssize_t r = 0;
4571
4572
    return;
4573
4574
    assert(a == mainloop_api);
4575
    assert(e);
4576
    assert(stdio_event == e);
4577
4578
    if (verbose) {
4579
      MDBGLOG("sound", "INFO\t[%s()]: called", __func__);
4580
    }
4581
4582
    TC_MUTEX_LOCK(mutex_buffer);
4583
4584
    if (buffer) {
4585
	TC_MUTEX_LOCK(mutex_event);
4586
        mainloop_api->io_enable(stdio_event, PA_IO_EVENT_NULL);
4587
	TC_MUTEX_UNLOCK(mutex_event);
4588
	TC_MUTEX_UNLOCK(mutex_buffer);
4589
        return;
4590
    }
4591
4592
    if (!stream || pa_stream_get_state(stream) != PA_STREAM_READY || !(l = w = pa_stream_writable_size(stream))) {
4593
        l = 4096;
4594
    }
4595
4596
    buffer = pa_xmalloc(l);
4597
4598
    if ((r = g_file_read(fd, buffer, l)) <= 0) {
4599
        if (r == 0) {
4600
            if (verbose) {
4601
                MDBGLOG("sound","INFO\t[%s()]: received EOF",__func__);
4602
	    }
4603
            start_drain();
4604
	}
4605
	else {
4606
	    //MDBGLOG("sound","ERROR\t[%s()]: read() failed (\"%s\")",__func__,strerror(errno));
4607
	    pa_quit(1);
4608
	}
4609
4610
	TC_MUTEX_LOCK(mutex_event);
4611
        mainloop_api->io_free(stdio_event);
4612
        stdio_event = NULL;
4613
	TC_MUTEX_UNLOCK(mutex_event);
4614
        return;
4615
    }
4616
4617
    buffer_length = (uint32_t) r;
4618
    buffer_index = 0;
4619
4620
    TC_MUTEX_UNLOCK(mutex_buffer);
4621
4622
    if (w) {
4623
	do_stream_write(w);
4624
    }
4625
}
4626
4627
/*****************************************************************************/
4628
/* Write some data to the stream */
4629
static void APP_CC do_stream_write(size_t length) {
4630
    size_t l;
4631
    assert(length);
4632
4633
    if (verbose) {
4634
      MDBGLOG("sound", "INFO\t[%s()]: called", __func__);
4635
    }
4636
4637
    TC_MUTEX_LOCK(mutex_buffer);
4638
4639
    if (!buffer || !buffer_length) {
4640
        return;
4641
    }
4642
4643
    l = length;
4644
    if (l > buffer_length) {
4645
        l = buffer_length;
4646
    }
4647
4648
    if (pa_stream_write(stream, (uint8_t*) buffer + buffer_index, l, NULL, 0, PA_SEEK_RELATIVE) < 0) {
4649
        MDBGLOG("sound","ERROR\t[%s()]: pa_stream_write() failed (\"%s\")", __func__, pa_strerror(pa_context_errno(context)));
4650
	TC_MUTEX_UNLOCK(mutex_buffer);
4651
        pa_quit(1);
4652
        return;
4653
    }
4654
4655
    buffer_length -= l;
4656
    buffer_index += l;
4657
4658
    if (!buffer_length) {
4659
        pa_xfree(buffer);
4660
        buffer = NULL;
4661
        buffer_index = buffer_length = 0;
4662
    }
4663
4664
    TC_MUTEX_UNLOCK(mutex_buffer);
4665
}
4666
4667
/*****************************************************************************/
4668
static void APP_CC stream_suspended_callback(pa_stream * s, void * userdata) {
4669
4670
    TC_MUTEX_LOCK(mutex_stream);
4671
4672
    assert(s);
4673
4674
    //if (verbose) {
4675
        if (pa_stream_is_suspended(s)) {
4676
            MDBGLOG("sound", "Stream device suspended.", __func__);
4677
	}
4678
        else {
4679
            MDBGLOG("sound", "Stream device resumed.", __func__);
4680
	}
4681
    //}
4682
4683
    TC_MUTEX_UNLOCK(mutex_stream);
4684
}
4685
4686
/*****************************************************************************/
4687
static void APP_CC stream_underflow_callback(pa_stream * s, void * userdata) {
4688
4689
    TC_MUTEX_LOCK(mutex_stream);
4690
4691
    assert(s);
4692
4693
    //if (verbose) {
4694
        MDBGLOG("sound", "INFO\t[%s()]: Stream underrun.", __func__);
4695
    //}
4696
4697
    TC_MUTEX_UNLOCK(mutex_stream);
4698
}
4699
4700
/*****************************************************************************/
4701
static void APP_CC stream_overflow_callback(pa_stream * s, void * userdata) {
4702
4703
    TC_MUTEX_LOCK(mutex_stream);
4704
4705
    assert(s);
4706
4707
    //if (verbose) {
4708
        MDBGLOG("sound", "INFO\t[%s()]: Stream overflow.", __func__);
4709
    //}
4710
4711
    TC_MUTEX_UNLOCK(mutex_stream);
4712
}
4713
4714
/*****************************************************************************/
4715
static void APP_CC stream_buffer_attr_callback(pa_stream * s, void * userdata) {
4716
4717
    TC_MUTEX_LOCK(mutex_stream);
4718
4719
    assert(s);
4720
4721
    //if (verbose) {
4722
        MDBGLOG("sound", "INFO\t[%s()]: Stream buffer attributes changed.", __func__);
4723
    //}
4724
4725
    TC_MUTEX_UNLOCK(mutex_stream);
4726
}
4727
4728
/*****************************************************************************/
4729
4730
static void APP_CC stream_write_callback(pa_stream * s, size_t len, void * userdata) {
4731
4732
    TC_MUTEX_LOCK(mutex_stream);
4733
4734
    assert(s);
4735
4736
    //if (verbose) {
4737
        MDBGLOG("sound", "INFO\t[%s()]: called", __func__);
4738
    //}
4739
4740
    TC_MUTEX_UNLOCK(mutex_stream);
4741
}
4742
4743
/*****************************************************************************/
4744
static void * APP_CC
4745
sound_timer_loop(void * arg) {
4746
    void * rv = (void *)NULL;
4747
    unsigned char l_ok = 1;
4748
    unsigned char done = 0;
4749
4750
    TC_BARR_WAIT(barr_formats);
4751
4752
    if (g_client_formats_received == 0 || g_client_format_index == 0) {
4753
      l_ok = 0;
4754
      TC_MUTEX_LOCK(mutex_formats);
4755
      if (g_client_formats_received == 0 || g_client_format_index == 0) {
4756
	TC_MUTEX_UNLOCK(mutex_formats);
4757
	g_sleep(3000);
4758
	TC_MUTEX_LOCK(mutex_sound);
4759
	TC_MUTEX_LOCK(mutex_formats);
4760
	if (g_client_format_index < 0) {
4761
	  TC_MUTEX_UNLOCK(mutex_formats);
4762
	  TC_MUTEX_LOCK(mutex_close);
4763
	  g_received_close_pdu = 1;
4764
	  TC_MUTEX_UNLOCK(mutex_close);
4765
	  sound_deinit();
4766
	}
4767
	else {
4768
	  TC_MUTEX_UNLOCK(mutex_formats);
4769
	  l_ok = 1;
4770
	}
4771
	TC_MUTEX_UNLOCK(mutex_sound);
4772
      }
4773
      else {
4774
	TC_MUTEX_UNLOCK(mutex_formats);
4775
	l_ok = 1;
4776
      }
4777
    }
4778
    if (l_ok > 0) {
4779
	TC_MUTEX_LOCK(mutex_pa);
4780
	if (g_pa_ready < 1) {
4781
	  g_pa_ready = 1;
4782
	}
4783
	if (cond_pa != NULL) {
4784
	  TC_COND_BROADCAST(cond_pa);
4785
	}
4786
	TC_MUTEX_UNLOCK(mutex_pa);
4787
    }
4788
4789
    TC_THREAD_EXIT(NULL);
4790
    return rv;
4791
}
4792
4793
4794
/*****************************************************************************/
4795
static void APP_CC pa_sink_info_cb(struct pa_context * c, const pa_sink_info * i, int is_last, void * userdata) {
4796
    assert(c);
4797
    MDBGLOG("sound","INFO\t[%s()]: called (c = %p, i = %p, userdata = %p)",__func__,c,i,userdata);
4798
    if (i == NULL) {
4799
	goto end;
4800
    }
4801
    else {
4802
	TC_MUTEX_LOCK(mutex_sink);
4803
	g_sink_index = i->index;
4804
	TC_MUTEX_UNLOCK(mutex_sink);
4805
	pa_sink_state_callback(c, i, userdata);
4806
	//pa_sink_input_info_cb();
4807
    }
4808
  end:;
4809
    pa_threaded_mainloop_signal(mt, 0);
4810
    return;
4811
}
4812
4813
/*****************************************************************************/
4814
static void APP_CC pa_source_info_cb(struct pa_context * c, const pa_source_info * i, int is_last, void * userdata) {
4815
    assert(c);
4816
    MDBGLOG("sound","INFO\t[%s()]: called (c = %p, i = %p, userdata = %p)",__func__,c,i,userdata);
4817
    if (i == NULL) {
4818
	goto end;
4819
    }
4820
    else {
4821
	TC_MUTEX_LOCK(mutex_sink);
4822
	//g_source_index = i->index;
4823
	TC_MUTEX_UNLOCK(mutex_sink);
4824
	pa_source_state_callback(c, i, userdata);
4825
	//pa_source_input_info_cb();
4826
    }
4827
  end:;
4828
    if (1) {
4829
      pa_threaded_mainloop_signal(mt, 0);
4830
    }
4831
    return;
4832
}
4833
4834
/*****************************************************************************/
4835
static void APP_CC pa_subscribe_cb(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void * userdata) {
4836
    unsigned char tlock = 0;
4837
    pa_operation * o = (pa_operation *)NULL;
4838
4839
    assert(c);
4840
4841
    if (verbose) {
4842
      MDBGLOG("sound","INFO\t[%s()]: called (index = %d)",__func__,index);
4843
    }
4844
4845
    if (!pa_threaded_mainloop_in_thread(mt)) {
4846
	pa_threaded_mainloop_lock(mt);
4847
	tlock = 1;
4848
    }
4849
    TC_MUTEX_LOCK(mutex_stream);
4850
    if (!stream ||
4851
        index != pa_stream_get_index(stream) ||
4852
        (t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE) &&
4853
         t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW))) {
4854
    }
4855
    if (stream != NULL) {
4856
	index != pa_stream_get_index(stream);
4857
    }
4858
    MDBGLOG("sound","INFO\t[%s()]: index = %d",__func__,index);
4859
    //if (!(o = pa_context_get_sink_info_by_index(c, index, &pa_sink_info_cb, NULL))) {
4860
    if (!(o = pa_context_get_source_info_by_index(c, index, &pa_source_info_cb, NULL))) {
4861
	pa_threaded_mainloop_unlock(mt);
4862
	TC_MUTEX_UNLOCK(mutex_stream);
4863
	MDBGLOG("ERROR\t[%s()]: pa_context_get_sink_info() failed (\"%s\")", __func__, pa_strerror(pa_context_errno(c)));
4864
	goto end;
4865
    }
4866
    else {
4867
	TC_MUTEX_UNLOCK(mutex_stream);
4868
	if (tlock) {
4869
	    pa_threaded_mainloop_wait(mt);
4870
	    pa_operation_unref(o);
4871
	    pa_threaded_mainloop_unlock(mt);
4872
	}
4873
	else {
4874
	    pa_operation_unref(o);
4875
	}
4876
    }
4877
    
4878
  end:;
4879
    if (tlock) {
4880
	MDBGLOG("sound","INFO\t[%s()]: (tlock = %d)",__func__,index,tlock);
4881
	pa_threaded_mainloop_unlock(mt);
4882
    }
4883
    return;
4884
}
4885
4886
static void APP_CC pa_context_success_cb(pa_context * c, int success, void * userdata) {
4887
    assert(c);
4888
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
4889
}
4890
4891
static void APP_CC pa_stream_latency_update_cb(pa_stream *s, void *userdata) {
4892
    assert(s);
4893
    MDBGLOG("sound","INFO\t[%s()]: called",__func__);
4894
    //pa_threaded_mainloop_signal(mainloop, 0);
4895
}
4896
4897
static int APP_CC sound_get_pulseaudio_server(const char ** server) {
4898
    int rv = 0;
4899
    glob_t tglob;
4900
    char globdir[164];
4901
    g_memset(globdir, 0, sizeof(globdir));
4902
    if (server == NULL) {
4903
      rv = -1;
4904
      goto end;
4905
    }
4906
    else {
4907
      *server = g_getenv("PULSE_SERVER");
4908
    }
4909
    if (*server == NULL) {
4910
      uid_t tuid = 0;
4911
      unsigned int idx = 0;
4912
      g_memset(&tglob,0,sizeof(glob_t));
4913
      pa_get_home_dir(globdir, sizeof(globdir) - 48);
4914
      g_strncat(globdir, "/.pulse/*-runtime/native", sizeof(globdir));
4915
      glob(globdir,GLOB_NOSORT,NULL,&tglob);
4916
      for (idx = 0; idx < tglob.gl_pathc; idx++) {
4917
	int fd = -1;
4918
	struct stat finfo;
4919
	g_memset(&finfo,0,sizeof(struct stat));
4920
	if (g_strlen(tglob.gl_pathv[idx]) > 0 && stat(tglob.gl_pathv[idx], &finfo) == 0) {
4921
	  if (S_ISSOCK(finfo.st_mode)) {
4922
	      *server = g_strndup(tglob.gl_pathv[idx], 164);
4923
	      break;
4924
	  }
4925
	}
4926
	else {
4927
	  continue;
4928
	}
4929
      }
4930
      globfree(&tglob);
4931
    }
4932
4933
  end:;
4934
    MDBGLOG("sound","DEBUG\t[%s()]: *server = \"%s\"",__func__,*server);
4935
    return rv;
4936
}
4937
4938
/* UNIX signal to quit recieved */
4939
static void APP_CC pa_exit_signal_callback(pa_mainloop_api * m, pa_signal_event * e, int sig, void * userdata) {
4940
    //if (verbose) {
4941
      MDBGLOG("sound","INFO\t[%s()]: received exit signal",__func__);
4942
    //}
4943
    pa_quit(0);
4944
}
4945
4946
static void APP_CC pa_sink_input_info_cb(pa_context * c, const pa_sink_input_info * i, int eol, void * userdata) {
4947
    MDBGLOG("sound","INFO\t[%s()]: called (eol = %d)",__func__,eol);
4948
    TC_MUTEX_LOCK(mutex_sink);
4949
    if (i != NULL && i->sink == g_sink_index) {
4950
	g_sink_input_count++;
4951
    }
4952
    if (eol > 0 && g_sink_query_waiting > 0) {
4953
	if (g_sink_query_waiting > 1) {
4954
	    TC_COND_BROADCAST(cond_sink);
4955
	}
4956
	else {
4957
	    TC_COND_SIGNAL(cond_sink);
4958
	}
4959
    }
4960
    TC_MUTEX_UNLOCK(mutex_sink);
4961
    return;
4962
}
4963
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/config.c (-12 / +12 lines)
 Lines 179-191    Link Here 
179
  }
179
  }
180
180
181
  /* showing read config */
181
  /* showing read config */
182
  /* g_printf("sesman config:\r\n");
182
  g_printf("sesman config:\r\n");
183
  g_printf("\tListenAddress:            %s\r\n", cf->listen_address);
183
  g_printf("\tListenAddress:            %s\r\n", cf->listen_address);
184
  g_printf("\tListenPort:               %s\r\n", cf->listen_port);
184
  g_printf("\tListenPort:               %s\r\n", cf->listen_port);
185
  g_printf("\tEnableUserWindowManager:  %i\r\n", cf->enable_user_wm);
185
  g_printf("\tEnableUserWindowManager:  %i\r\n", cf->enable_user_wm);
186
  g_printf("\tUserWindowManager:        %s\r\n", cf->user_wm);
186
  g_printf("\tUserWindowManager:        %s\r\n", cf->user_wm);
187
  g_printf("\tDefaultWindowManager:     %s\r\n", cf->default_wm);
187
  g_printf("\tDefaultWindowManager:     %s\r\n", cf->default_wm);
188
  g_printf("\tAuthFilePath:             %s\r\n", ((cf->auth_file_path) ? (cf->auth_file_path) : ("disabled"))); */
188
  g_printf("\tAuthFilePath:             %s\r\n", ((cf->auth_file_path) ? (cf->auth_file_path) : ("disabled")));
189
189
190
  return 0;
190
  return 0;
191
}
191
}
 Lines 236-246    Link Here 
236
    lc->log_file=g_strdup("./sesman.log");
236
    lc->log_file=g_strdup("./sesman.log");
237
  }
237
  }
238
238
239
  /* g_printf("logging configuration:\r\n");
239
  g_printf("logging configuration:\r\n");
240
  g_printf("\tLogFile:       %s\r\n",lc->log_file);
240
  g_printf("\tLogFile:       %s\r\n",lc->log_file);
241
  g_printf("\tLogLevel:      %i\r\n", lc->log_level);
241
  g_printf("\tLogLevel:      %i\r\n", lc->log_level);
242
  g_printf("\tEnableSyslog:  %i\r\n", lc->enable_syslog);
242
  g_printf("\tEnableSyslog:  %i\r\n", lc->enable_syslog);
243
  g_printf("\tSyslogLevel:   %i\r\n", lc->syslog_level); */
243
  g_printf("\tSyslogLevel:   %i\r\n", lc->syslog_level);
244
244
245
  return 0;
245
  return 0;
246
}
246
}
 Lines 295-301    Link Here 
295
  }
295
  }
296
296
297
  /* printing security config */
297
  /* printing security config */
298
  /* g_printf("security configuration:\r\n");
298
  g_printf("security configuration:\r\n");
299
  g_printf("\tAllowRootLogin:       %i\r\n",sc->allow_root);
299
  g_printf("\tAllowRootLogin:       %i\r\n",sc->allow_root);
300
  g_printf("\tMaxLoginRetry:        %i\r\n",sc->login_retry);
300
  g_printf("\tMaxLoginRetry:        %i\r\n",sc->login_retry);
301
  if (sc->ts_users_enable)
301
  if (sc->ts_users_enable)
 Lines 313-319    Link Here 
313
  else
313
  else
314
  {
314
  {
315
    g_printf("\tNo TSAdminsGroup defined\r\n");
315
    g_printf("\tNo TSAdminsGroup defined\r\n");
316
    } */
316
  }
317
317
318
  return 0;
318
  return 0;
319
}
319
}
 Lines 358-368    Link Here 
358
  }
358
  }
359
359
360
  /* printing security config */
360
  /* printing security config */
361
  /* g_printf("session configuration:\r\n");
361
  g_printf("session configuration:\r\n");
362
  g_printf("\tMaxSessions:                 %i\r\n", se->max_sessions);
362
  g_printf("\tMaxSessions:                 %i\r\n", se->max_sessions);
363
  g_printf("\tKillDisconnected:            %i\r\n", se->kill_disconnected);
363
  g_printf("\tKillDisconnected:            %i\r\n", se->kill_disconnected);
364
  g_printf("\tIdleTimeLimit:               %i\r\n", se->max_idle_time);
364
  g_printf("\tIdleTimeLimit:               %i\r\n", se->max_idle_time);
365
  g_printf("\tDisconnectedTimeLimit:       %i\r\n", se->max_idle_time); */
365
  g_printf("\tDisconnectedTimeLimit:       %i\r\n", se->max_idle_time);
366
366
367
  return 0;
367
  return 0;
368
}
368
}
 Lines 386-396    Link Here 
386
  }
386
  }
387
387
388
  /* printing security config */
388
  /* printing security config */
389
  /* g_printf("X11rdp parameters:\r\n");
389
  g_printf("X11rdp parameters:\r\n");
390
  for (i = 0; i < cs->rdp_params->count; i++)
390
  for (i = 0; i < cs->rdp_params->count; i++)
391
  {
391
  {
392
    g_printf("\tParameter %02d                   %s\r\n", i, (char*)list_get_item(cs->rdp_params, i));
392
    g_printf("\tParameter %02d                   %s\r\n", i, (char*)list_get_item(cs->rdp_params, i));
393
    } */
393
  }
394
394
395
  return 0;
395
  return 0;
396
}
396
}
 Lines 414-424    Link Here 
414
  }
414
  }
415
415
416
  /* printing security config */
416
  /* printing security config */
417
  /* g_printf("Xvnc parameters:\r\n");
417
  g_printf("Xvnc parameters:\r\n");
418
  for (i = 0; i < cs->vnc_params->count; i++)
418
  for (i = 0; i < cs->vnc_params->count; i++)
419
  {
419
  {
420
    g_printf("\tParameter %02d                   %s\r\n", i, (char*)list_get_item(cs->vnc_params, i));
420
    g_printf("\tParameter %02d                   %s\r\n", i, (char*)list_get_item(cs->vnc_params, i));
421
    } */
421
  }
422
422
423
  return 0;
423
  return 0;
424
}
424
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/dynamic/Makefile.am (+40 lines)
Line 0    Link Here 
1
2
AM_CFLAGS = \
3
  -pthread \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED \
12
  -D_POSIX_PTHREAD_SEMATICS \
13
  -D_POSIX_PTHREADS
14
15
16
LDFLAGS = \
17
  -lpthread
18
19
INCLUDES = \
20
  -I$(top_srcdir)/common
21
22
LDADD = \
23
  $(top_builddir)/common/libcommon.la
24
25
sbin_PROGRAMS = \
26
  xrdp_drdynvc_interface \
27
  xrdp_rdpeai
28
29
xrdp_drdynvc_interface_SOURCES = \
30
  xrdp_drdynvc_interface.c \
31
  xrdp_drdynvc_interface.h
32
33
xrdp_rdpeai_SOURCES = \
34
  xrdp_rdpeai.c \
35
  xrdp_rdpeai.h
36
37
xrdp_rdpeai_LDFLAGS = \
38
  -lpulse \
39
  -lpulse-simple \
40
  -lgsm
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/dynamic/xrdp_drdynvc_interface.c (+958 lines)
Line 0    Link Here 
1
2
#include "xrdp_drdynvc_interface.h"
3
4
static const char		sockpath[]	= "/tmp/.audio_input_socket";
5
static const char		intsockname[]	= "audio_interface_socket";
6
static const char		inpipepath[]	= "/tmp/audio_input_inpipe";
7
static const char		outpipepath[]	= "/tmp/audio_input_outpipe";
8
9
static char *			g_laddr		= (char *)NULL;
10
static char *			g_lport		= (char *)NULL;
11
12
static volatile unsigned char	g_done = 0;
13
static int			g_interface_type = WO_LOCAL;
14
15
static stream_list_t *		ilist = (stream_list_t *)NULL;
16
static stream_list_t *		olist = (stream_list_t *)NULL;
17
static stream_list_t *		dlist = (stream_list_t *)NULL;
18
static volatile int		ilist_count = 0;
19
static volatile int		olist_count = 0;
20
static volatile int		dlist_count = 0;
21
22
static struct stream *		g_ins = (struct stream *)NULL;
23
static tbus			g_sck = -1;
24
static int			g_uniqid = 0;
25
static volatile tbus		g_channel_id = -1;
26
27
static const unsigned int	g_trans_socket_type = WO_LOCAL;
28
static struct trans *		g_trans = (struct trans *)NULL;
29
30
static tc_t			g_thread_barr;
31
static tc_p			barr_thread = &g_thread_barr;
32
static tc_t			g_loop_barr;
33
static tc_p			barr_loop = &g_loop_barr;
34
35
static tc_t			g_recv_thread;
36
static tc_p			thread_recv = &g_recv_thread;
37
static tc_t			g_send_thread;
38
static tc_p			thread_send = &g_send_thread;
39
40
static tc_t			g_inpipe_thread;
41
static tc_p			thread_inpipe = &g_inpipe_thread;
42
static tc_t			g_outpipe_thread;
43
static tc_p			thread_outpipe = &g_outpipe_thread;
44
45
static tc_t			g_ins_mutex = TC_MUTEX_INITIALIZER;
46
static tc_p			mutex_ins = &g_ins_mutex;
47
static tc_t			g_ilist_mutex = TC_MUTEX_INITIALIZER;
48
static tc_p			mutex_ilist = &g_ilist_mutex;
49
static tc_t			g_olist_mutex = TC_MUTEX_INITIALIZER;
50
static tc_p			mutex_olist = &g_olist_mutex;
51
static tc_t			g_dlist_mutex = TC_MUTEX_INITIALIZER;
52
static tc_p			mutex_dlist = &g_dlist_mutex;
53
static tc_t			g_done_mutex = TC_MUTEX_INITIALIZER;
54
static tc_p			mutex_done = &g_done_mutex;
55
static tc_t			g_sck_mutex = TC_MUTEX_INITIALIZER;
56
static tc_p			mutex_sck = &g_sck_mutex;
57
static tc_t			g_say_mutex = TC_MUTEX_INITIALIZER;
58
static tc_p			mutex_say = &g_say_mutex;
59
static tc_t			g_id_mutex = TC_MUTEX_INITIALIZER;
60
static tc_p			mutex_id = &g_id_mutex;
61
62
static tc_t			g_ilist_cond = TC_COND_INITIALIZER;
63
static tc_p			cond_ilist = &g_ilist_cond;
64
static tc_t			g_olist_cond = TC_COND_INITIALIZER;
65
static tc_p			cond_olist = &g_olist_cond;
66
static tc_t			g_dlist_cond = TC_COND_INITIALIZER;
67
static tc_p			cond_dlist = &g_dlist_cond;
68
static tc_t			g_sck_cond = TC_COND_INITIALIZER;
69
static tc_p			cond_sck = &g_sck_cond;
70
71
static tc_t			g_pending_mutex = TC_MUTEX_INITIALIZER;
72
static tc_p			mutex_pending = &g_pending_mutex;
73
static tc_t			g_pending_cond = TC_COND_INITIALIZER;
74
static tc_p			cond_pending = &g_pending_cond;
75
76
static DYNVC_ANY		g_pdu;
77
static volatile unsigned char	g_pending = 0;
78
static volatile unsigned int	g_pending_waiting = 0;
79
static volatile unsigned int	g_ilist_waiting = 0;
80
static volatile unsigned int	g_ilist_triggered = 0;
81
static volatile unsigned int	g_olist_waiting = 0;
82
static volatile unsigned int	g_olist_triggered = 0;
83
static volatile unsigned int	g_dlist_waiting = 0;
84
static volatile unsigned int	g_dlist_triggered = 0;
85
86
int APP_CC main(int, char * []);
87
static int APP_CC init_locks(void);
88
static int APP_CC launch_threads(void);
89
static void * APP_CC recv_loop(void *);
90
static void * APP_CC send_loop(void *);
91
static void * APP_CC inpipe_loop(void *);
92
static void * APP_CC outpipe_loop(void *);
93
static int APP_CC handle_create(const char *, uint32_t);
94
static int APP_CC handle_close(uint32_t);
95
static int APP_CC handle_data(int, tbus);
96
static int APP_CC get_connection(tbus *, const char *, const char *);
97
static size_t APP_CC inpipe_data_in(struct trans *);
98
99
static int dynamic_channel_id = -1;
100
101
#define	NUM_THREADS	5
102
103
int APP_CC main(int argc, char * argv[]) {
104
    int rv = 0;
105
    tbus sck = -1;
106
    char * caddr = (char *)NULL;
107
    char * cport = "7712";
108
    char * laddr = (char *)NULL;
109
    char * lport = "7714";
110
    unsigned char done = 0;
111
112
    g_memset(&g_pdu, 0, sizeof(DYNVC_ANY));
113
114
    make_stream(g_ins);
115
    init_stream(g_ins, MAX_STREAM);
116
117
    if (argc > 1 && argv[1] != NULL && g_strlen(argv[1]) > 0) {
118
      char * cpos = (char *)NULL;
119
      cpos = g_strchr(argv[1],':');
120
      if (cpos == NULL) {
121
	caddr = g_strndup(argv[1],64);
122
      }
123
      else {
124
	cport = g_strndup(cpos,10);
125
	caddr = g_strndup(argv[1],(cpos - argv[1]));
126
      }
127
      if (argc > 2 && argv[2] != NULL && g_strlen(argv[2]) > 0) {
128
	laddr = g_strndup(argv[2],64);;
129
	lport = (char *)NULL;
130
	g_laddr = laddr;
131
	g_lport = lport;
132
      }
133
    }
134
135
    init_locks();
136
    launch_threads();
137
138
    TC_MUTEX_LOCK(mutex_sck);
139
    if ((rv = get_connection(&sck, caddr, cport)) == 0) {
140
      g_sck = sck;
141
    }
142
    else {
143
      SAY("failed to establish connection (rv = %d, sck = %d)", rv, sck);
144
      rv = -1;
145
      TC_MUTEX_LOCK(mutex_done);
146
      g_done = 1;
147
      TC_MUTEX_UNLOCK(mutex_done);
148
      g_sck = -1;
149
      TC_MUTEX_UNLOCK(mutex_sck);
150
      goto end;
151
    }
152
    TC_MUTEX_UNLOCK(mutex_sck);
153
    TC_BARR_WAIT(barr_thread);
154
    TC_BARR_WAIT(barr_loop);
155
156
    handle_create("AUDIO_INPUT", 0);
157
158
    TC_MUTEX_LOCK(mutex_done);
159
    done = g_done;
160
    TC_MUTEX_UNLOCK(mutex_done);
161
    while (!done) {
162
      if (g_pending == 0) {
163
	TC_MUTEX_LOCK(mutex_pending);
164
	g_pending_waiting++;
165
	if (g_pending == 0) {
166
	  TC_COND_WAIT(cond_pending, mutex_pending);
167
	}
168
	g_pending_waiting--;
169
	TC_MUTEX_UNLOCK(mutex_pending);
170
      }
171
      if (g_done == 0) {
172
	char * cmd = (char *)NULL;
173
	tbus tstdin = -1;
174
	tstdin = STDIN_FILENO;
175
	tbus ifd = -1;
176
	if (!g_strcmp(cmd,"data")) {
177
	  int cnum = 0;
178
	  if (argc > 3 && argv[3] != NULL && g_strlen(argv[3]) > 0) {
179
	    cnum = g_atoi(argv[3]);
180
	  }
181
	  if (argc > 4 && argv[4] != NULL && g_strlen(argv[4]) > 0) {
182
	    ifd = g_file_open(argv[4]);
183
	    if (ifd < 1) {
184
	      SAY("failed to open \"%s\"",argv[4]);
185
	    }
186
	  }
187
	  else {
188
	    ifd = (tbus)tstdin;
189
	  }
190
	  if (ifd > -1) {
191
	    handle_data(cnum, (const tbus)ifd);
192
	  }
193
	}
194
	else if (!g_strcmp(cmd,"close")) {
195
	  int cnum = 0;
196
	  if (argc > 3 && argv[3] != NULL && g_strlen(argv[3]) > 0) {
197
	    cnum = g_atoi(argv[3]);
198
	  }
199
	  handle_close(cnum);
200
	}
201
      }
202
      TC_MUTEX_LOCK(mutex_done);
203
      done = g_done;
204
      TC_MUTEX_UNLOCK(mutex_done);
205
    }
206
207
    TC_THREAD_JOIN(thread_recv->thread, NULL);
208
    TC_THREAD_JOIN(thread_send->thread, NULL);
209
    TC_THREAD_JOIN(thread_inpipe->thread, NULL);
210
    TC_THREAD_JOIN(thread_outpipe->thread, NULL);
211
212
    if (g_sck > -1) {
213
      close(g_sck);
214
      g_sck = -1;
215
    }
216
217
  end:;
218
    g_sleep(200);
219
    return rv;
220
}
221
222
static int APP_CC init_locks() {
223
    int rv = 0;
224
    tc_t mattr;
225
    tc_p pmattr = &mattr;
226
    tc_t cattr;
227
    tc_p pcattr = &cattr;
228
229
    g_memset(pmattr, 0, sizeof(tc_t));
230
    g_memset(pcattr, 0, sizeof(tc_t));
231
232
    TC_MUTATTR_INIT(pmattr);
233
    TC_MUTEX_INIT(mutex_ins, pmattr);
234
    TC_MUTEX_INIT(mutex_ilist, pmattr);
235
    TC_MUTEX_INIT(mutex_olist, pmattr);
236
    TC_MUTEX_INIT(mutex_dlist, pmattr);
237
    TC_MUTEX_INIT(mutex_done, pmattr);
238
    TC_MUTEX_INIT(mutex_sck, pmattr);
239
    TC_MUTEX_INIT(mutex_pending, pmattr);
240
    TC_MUTEX_INIT(mutex_say, pmattr);
241
242
    TC_CONDATTR_INIT(pcattr);
243
    TC_COND_CREATE(cond_ilist, pcattr);
244
    TC_COND_CREATE(cond_olist, pcattr);
245
    TC_COND_CREATE(cond_dlist, pcattr);
246
    TC_COND_CREATE(cond_sck, pcattr);
247
    TC_COND_CREATE(cond_pending, pcattr);
248
249
    TC_BARR_INIT(barr_thread, NUM_THREADS);
250
    TC_BARR_INIT(barr_loop, NUM_THREADS);
251
252
    return rv;
253
}
254
255
static int APP_CC launch_threads() {
256
    int rv = 0;
257
    tc_t attr;
258
    tc_p pattr = &attr;
259
260
    g_memset(pattr, 0, sizeof(tc_t));
261
    TC_THREADATTR_INIT(pattr);
262
    TC_THREADATTR_SETDETACHSTATE(pattr, TC_CREATE_JOINABLE);
263
264
    TC_THREAD_INIT_FULL(&(thread_recv->thread), &(pattr->threadattr), &recv_loop, NULL);
265
    TC_THREAD_INIT_FULL(&(thread_send->thread), &(pattr->threadattr), &send_loop, NULL);
266
267
    TC_THREAD_INIT_FULL(&(thread_inpipe->thread), &(pattr->threadattr), &inpipe_loop, g_laddr);
268
    TC_THREAD_INIT_FULL(&(thread_outpipe->thread), &(pattr->threadattr), &outpipe_loop, NULL);
269
270
    return rv;
271
}
272
273
static void * APP_CC send_loop(void * arg) {
274
    void * rv = (void *)NULL;
275
    unsigned char done = 0;
276
    unsigned char past_barrier = 0;
277
    unsigned char loop_done = 0;
278
    TC_BARR_WAIT(barr_thread);
279
    TC_MUTEX_LOCK(mutex_done);
280
    done = g_done;
281
    TC_MUTEX_UNLOCK(mutex_done);
282
    while (!done) {
283
      unsigned char cont = 0;
284
      stream_list_t lentry; // = (stream_list_t *)NULL;
285
      stream_list_t * entry = &lentry;
286
      struct stream * s = (struct stream *)NULL;
287
      int cnt = 0;
288
      TC_MUTEX_LOCK(mutex_olist);
289
      if (!loop_done) {
290
	TC_BARR_WAIT(barr_loop);
291
	loop_done = 1;
292
      }
293
      if (olist_count < 1) {
294
	g_olist_waiting++;
295
	TC_COND_WAIT(cond_olist, mutex_olist);
296
	g_olist_waiting--;
297
	if (g_olist_triggered < 1) {
298
	  cont = 1;
299
	}
300
	g_olist_triggered = 0;
301
      }
302
      TC_MUTEX_UNLOCK(mutex_olist);
303
      if (cont > 0) {
304
	continue;
305
      }
306
      TC_MUTEX_LOCK(mutex_olist);
307
      entry = NULL;
308
      if (olist_count > 0) {
309
	SQ_DEQ(olist, &entry);
310
	olist_count--;
311
      }
312
      if (entry == NULL) {
313
	TC_MUTEX_UNLOCK(mutex_olist);
314
	SAY("deq'd entry is NULL");
315
      }
316
      else {
317
	size_t len = 0;
318
	TC_MUTEX_UNLOCK(mutex_olist);
319
	s = entry->s;
320
	len = (s == NULL || s->data == NULL || s->p == NULL || s->end == NULL || s->p < s->data || s->end <= s->p || s->size < 1 || (s->end - s->data) > s->size || (s->end - s->p) > s->size) ? 0 : (s->end - s->data);
321
	if (len < 1) {
322
	  SAY("len is zero (s = %p, s->p = %p, s->end = %p, s->data = %p, s->size = %d)",s,s->p,s->end,s->data,s->size);
323
	}
324
	else {
325
	  if (g_sck > -1 && g_tcp_socket_ok(g_sck) && g_tcp_can_send(g_sck, 50)) {
326
	    size_t rlen = 0;
327
	    rlen = g_tcp_send_force(g_sck, s->p, len, 0);
328
	  }
329
	  else {
330
	    SAY("unable to send on socket %d",g_sck);
331
	  }
332
	}
333
      }
334
      TC_MUTEX_LOCK(mutex_done);
335
      done = g_done;
336
      TC_MUTEX_UNLOCK(mutex_done);
337
    }
338
    TC_THREAD_EXIT(NULL);
339
    return rv;
340
}
341
342
static void * APP_CC recv_loop(void * arg) {
343
    void * rv = (void *)NULL;
344
    unsigned char done = 0;
345
    unsigned char past_barrier = 0;
346
    unsigned char got_ok = 0;
347
    tbus fd = -1;
348
349
    TC_BARR_WAIT(barr_thread);
350
    fd = g_sck;
351
352
    if (fd < 1) {
353
      SAY("invalid wait object");
354
    }
355
    else {
356
      tbus sck = -1;
357
      TC_MUTEX_LOCK(mutex_done);
358
      done = g_done;
359
      TC_MUTEX_UNLOCK(mutex_done);
360
      TC_BARR_WAIT(barr_loop);
361
      while (!done) {
362
	unsigned char is_ok = 0;
363
	if (g_obj_wait(&fd, 1, NULL, 0, 0) < 0) {
364
	}
365
	else if (g_is_wait_obj_set(fd)) {
366
	  unsigned char empty = 0;
367
	  unsigned char buf[MAX_STREAM];
368
	  size_t blen = 0;
369
	  struct stream * s = (struct stream *)NULL;
370
	  g_memset(buf,0,sizeof(buf));
371
	  while (g_done == 0 && g_tcp_can_recv(fd, 50) && (blen = g_tcp_recv(fd, buf, 4096, 0)) > 0) {
372
	    struct stream *	s = (struct stream *)NULL;
373
	    stream_list_t *     entry = (stream_list_t *)NULL;
374
	    if (g_channel_id < 0 && blen > 3 && buf[0] == 'O' && buf[1] == 'K' && buf[2] == '\n') {
375
	      char nbuf[7] = {0,0,0,0,0,0,0};
376
	      char c = 0;
377
	      ptrdiff_t i = 3;
378
	      c = buf[i];
379
	      while ((i - 3) < blen && i < 9 && (c >= '0' && c <= '9')) {
380
		nbuf[(i - 3)] = c;
381
		i++;
382
		c = buf[i];
383
	      }
384
	      if (g_strlen(nbuf) > 0) {
385
		TC_MUTEX_LOCK(mutex_id);
386
		g_channel_id = g_atoi(nbuf);
387
		TC_MUTEX_UNLOCK(mutex_id);
388
		is_ok = 1;
389
	      }
390
	    }
391
	    if (!is_ok) {
392
	      blen = MIN(blen, sizeof(buf));
393
	      if (blen > 0) {
394
		make_stream(s);
395
		init_stream(s, sizeof(buf));
396
		entry = (stream_list_t *)g_malloc(sizeof(stream_list_t), 1);
397
		out_uint8a(s, buf, blen);
398
		s_mark_end(s);
399
		s->p = s->data;
400
		entry->s = s;
401
		TC_MUTEX_LOCK(mutex_ilist);
402
		SQ_ENQ(ilist, entry);
403
		ilist_count++;
404
		SAY("enq'd entry (%p; blen = %d)",entry,blen);
405
		if (g_ilist_waiting > 0) {
406
		  g_ilist_triggered = 1;
407
		  if (g_ilist_waiting > 1) {
408
		    TC_COND_BROADCAST(cond_ilist);
409
		  }
410
		  else {
411
		    TC_COND_SIGNAL(cond_ilist);
412
		  }
413
		}
414
		TC_MUTEX_UNLOCK(mutex_ilist);
415
	      }
416
	    }
417
	    g_memset(buf,0,sizeof(buf));
418
	  }
419
	}
420
	if (g_done > 0) {
421
	  TC_MUTEX_LOCK(mutex_done);
422
	  done = g_done;
423
	  TC_MUTEX_UNLOCK(mutex_done);
424
	}
425
      }
426
    }
427
428
  end:;
429
    SAY("done");
430
    TC_THREAD_EXIT(NULL);
431
    return rv;
432
}
433
434
static int APP_CC get_connection(tbus * fd, const char * iaddress, const char * iport) {
435
    int rv = 0;
436
    tbus sck = -1;
437
    char * addr = "localhost";
438
    char * port = "7712";
439
440
    if (fd == NULL) {
441
      SAY("NULL input");
442
      rv = -1;
443
    }
444
    else {
445
      unsigned char is_local = 0;
446
      if (iaddress != NULL && g_strlen(iaddress) > 0) {
447
	addr = (char *)iaddress;
448
      }
449
      if (iport != NULL && g_strlen(iport) > 0) {
450
	port = (char *)iport;
451
      }
452
      if (addr != NULL && g_strlen(addr) > 0 && g_strchr(addr, '/') != NULL) {
453
	is_local = 1;
454
      }
455
      else {
456
	is_local = 0;
457
      }
458
      if (is_local) {
459
	SAY("(using local socket)");
460
        if ((sck = g_tcp_local_socket()) < 1) {
461
	  rv = -2;
462
        }
463
        else {
464
	  rv = g_tcp_local_connect(sck, addr);
465
        }
466
      }
467
      else {
468
        if ((sck = g_tcp_socket()) < 1) {
469
	  rv = -2;
470
        }
471
        else {
472
	  rv = g_tcp_connect(sck, addr, port);
473
        }
474
      }
475
      *fd = sck;
476
    }
477
478
    return rv;
479
}
480
481
static int APP_CC handle_create(const char * cname, uint32_t cnum) {
482
    int			rv = 0;
483
    DYNVC_CREATE_REQ *	pdu = (DYNVC_CREATE_REQ *)(&(g_pdu.create_req));
484
    const uint32_t	magic = RDP_PACKET_MAGIC;
485
    uint32_t		cmd = RDPCHAN_OPEN;
486
    uint32_t		size = 0;
487
    uint32_t		chanid = cnum;
488
    uint32_t		uniqid = 0;
489
    uint32_t		crc32 = 0;
490
    struct stream *	s = (struct stream *)NULL;
491
    stream_list_t *	entry = (stream_list_t *)NULL;
492
    char *		p = (char *)NULL;
493
    uint32_t *		p_crc32 = (uint32_t *)NULL;
494
495
    make_stream(s);
496
    init_stream(s, MAX_STREAM);
497
    entry = (stream_list_t *)g_malloc(sizeof(stream_list_t), 1);
498
    construct_DYNVC_CREATE_REQ(pdu);
499
    g_snprintf(pdu->ChannelName,48,cname);
500
    size = g_strlen(pdu->ChannelName);
501
    uniqid = g_uniqid++;
502
    out_uint32_le(s, magic);
503
    out_uint32_le(s, cmd);
504
    out_uint32_le(s, size);
505
    out_uint32_le(s, chanid);
506
    out_uint32_le(s, uniqid);
507
    p_crc32 = (uint32_t *)(s->p);
508
    out_uint32_le(s, crc32);
509
    p = s->p;
510
    out_uint8a(s, pdu->ChannelName, g_strlen(pdu->ChannelName));
511
    s_mark_end(s);
512
    *p_crc32 = Crc32_ComputeBuf(0, p, (s->end - p) - 1);
513
    s->p = s->data;
514
    entry->s = s;
515
    TC_MUTEX_LOCK(mutex_olist);
516
    SQ_ENQ(olist, entry);
517
    olist_count++;
518
    TC_MUTEX_UNLOCK(mutex_olist);
519
    TC_MUTEX_LOCK(mutex_olist);
520
    if (g_olist_waiting > 0) {
521
      g_olist_triggered = 1;
522
      if (g_olist_waiting > 1) {
523
	TC_COND_BROADCAST(cond_olist);
524
      }
525
      else {
526
	TC_COND_SIGNAL(cond_olist);
527
      }
528
    }
529
    TC_MUTEX_UNLOCK(mutex_olist);
530
531
    return rv;
532
}
533
534
static int APP_CC handle_close(uint32_t cnum) {
535
    int			rv = 0;
536
    DYNVC_CLOSE *	pdu = (DYNVC_CLOSE *)(&(g_pdu.close));
537
    const uint32_t	magic = RDP_PACKET_MAGIC;
538
    uint32_t		cmd = RDPCHAN_CLOSE;
539
    uint32_t		size = 0;
540
    uint32_t		chanid = cnum;
541
    uint32_t		uniqid = 0;
542
    uint32_t		crc32 = 0;
543
    struct stream *	s = (struct stream *)NULL;
544
    stream_list_t *	entry = (stream_list_t *)NULL;
545
    char *		p = (char *)NULL;
546
    uint32_t *		p_crc32 = (uint32_t *)NULL;
547
548
    make_stream(s);
549
    init_stream(s, MAX_STREAM);
550
    entry = (stream_list_t *)g_malloc(sizeof(stream_list_t), 1);
551
    construct_DYNVC_CLOSE(pdu);
552
    pdu->ChannelId = 1;
553
    uniqid = g_uniqid++;
554
    out_uint32_le(s, magic);
555
    out_uint32_le(s, cmd);
556
    out_uint32_le(s, size);
557
    out_uint32_le(s, chanid);
558
    out_uint32_le(s, uniqid);
559
    out_uint32_le(s, crc32);
560
    s_mark_end(s);
561
    s->p = s->data;
562
    entry->s = s;
563
    TC_MUTEX_LOCK(mutex_olist);
564
    SQ_ENQ(olist, entry);
565
    olist_count++;
566
    TC_MUTEX_UNLOCK(mutex_olist);
567
    TC_MUTEX_LOCK(mutex_olist);
568
    if (g_olist_waiting > 0) {
569
      g_olist_triggered = 1;
570
      TC_COND_SIGNAL(cond_olist);
571
    }
572
    TC_MUTEX_UNLOCK(mutex_olist);
573
    TC_MUTEX_LOCK(mutex_ilist);
574
    if (g_ilist_waiting > 0) {
575
      g_ilist_triggered = 1;
576
      TC_COND_SIGNAL(cond_ilist);
577
    }
578
    TC_MUTEX_UNLOCK(mutex_ilist);
579
580
    return rv;
581
}
582
583
static int APP_CC handle_data(int cnum, tbus fd) {
584
    int			rv = 0;
585
    DYNVC_DATA_FIRST *	first = (DYNVC_DATA_FIRST *)(&(g_pdu.datafirst));
586
    DYNVC_DATA *	pdu = (DYNVC_DATA *)(&(g_pdu.data));
587
    const uint32_t	magic = RDP_PACKET_MAGIC;
588
    uint32_t		cmd = RDPCHAN_OPEN;
589
    uint32_t		size = 0;
590
    uint32_t		chanid = cnum;
591
    uint32_t		uniqid = 0;
592
    uint32_t		crc32 = 0;
593
    struct stream *	s = (struct stream *)NULL;
594
    stream_list_t *	entry = (stream_list_t *)NULL;
595
    uint32_t *		p_crc32 = (uint32_t *)NULL;
596
    char *		p = (char *)NULL;
597
    uint8_t		buf[4096];
598
    unsigned char	done = 0;
599
    unsigned int	cnt = 0;
600
    size_t		len = 0;
601
    size_t		total = 0;
602
    const size_t	dflen = 1 + 1 + 1 + 4 + 4;
603
    const size_t	dlen = 1 + 1 + 1 + 4;
604
    const size_t	max_pdu = 1600;
605
    const size_t	dfmax = max_pdu - dflen;
606
    const size_t	dmax = max_pdu - dlen;
607
608
    while (!done) {
609
      g_memset(buf,0,sizeof(buf));
610
      if (g_trans_socket_type == WO_FIFO || g_trans_socket_type == 0) {
611
	len = g_file_read(fd, buf, dfmax);
612
      }
613
      else if (g_trans_socket_type == WO_LOCAL || g_trans_socket_type == WO_INET) {
614
	len = g_tcp_recv(fd, buf, dmax, 0);
615
      }
616
      total += len;
617
      if (len < dmax) {
618
	done = 1;
619
      }
620
      while (len > 0) {
621
	size_t ulen = 0;
622
	if (cnt == 0 && len >= dmax) {
623
	  cmd = RDPCHAN_DATAFIRST;
624
	}
625
	else {
626
	  cmd = RDPCHAN_DATA;
627
	}
628
	make_stream(s);
629
	init_stream(s, MAX_STREAM);
630
	entry = (stream_list_t *)g_malloc(sizeof(stream_list_t), 1);
631
	uniqid = g_uniqid++;
632
	ulen = len;
633
	if (cmd == RDPCHAN_DATAFIRST) {
634
	  ulen += 4;
635
	}
636
	size = MIN(ulen, ((cmd == RDPCHAN_DATAFIRST) ? dfmax : dmax));
637
	out_uint32_le(s, magic);
638
	out_uint32_le(s, cmd);
639
	out_uint32_le(s, size);
640
	out_uint32_le(s, chanid);
641
	out_uint32_le(s, uniqid);
642
	p_crc32 = (uint32_t *)(s->p);
643
	out_uint32_le(s, crc32);
644
	if (cmd == RDPCHAN_DATAFIRST) {
645
	  out_uint32_le(s, len);
646
	}
647
	p = s->p;
648
	if (len > 0 && buf != NULL) {
649
	  out_uint8a(s, buf, len);
650
	}
651
	s_mark_end(s);
652
	if (s->end > p && (s->end - p) > 1) {
653
	  *p_crc32 = Crc32_ComputeBuf(0, p, (s->end - p) - 1);
654
	}
655
	s->p = s->data;
656
	entry->s = s;
657
	TC_MUTEX_LOCK(mutex_olist);
658
	SQ_ENQ(olist, entry);
659
	olist_count++;
660
	TC_MUTEX_UNLOCK(mutex_olist);
661
	TC_MUTEX_LOCK(mutex_olist);
662
	if (g_olist_waiting > 0) {
663
	  g_olist_triggered = 1;
664
	  TC_COND_SIGNAL(cond_olist);
665
	}
666
	TC_MUTEX_UNLOCK(mutex_olist);
667
	len -= size;
668
	s = (struct stream *)NULL;
669
	cnt++;
670
      }
671
    }
672
673
    return rv;
674
}
675
676
static void * APP_CC inpipe_loop(void * arg) {
677
    void * rv = (void *)NULL;
678
    unsigned char done = 0;
679
    unsigned char locked = 0;
680
    unsigned char ready = 0;
681
    tbus fd = -1;
682
    tbus ** objs = (tbus **)NULL;
683
    int tres = 0;
684
    int lres = 0;
685
    char * tpath = (char *)NULL;
686
687
    if (g_interface_type == WO_FIFO || g_interface_type == 0) {
688
      if (!g_file_exist(inpipepath)) {
689
        g_create_fifo(inpipepath);
690
      }
691
      fd = g_fifo_open(inpipepath);
692
      fd = g_create_wait_obj_from_fifo(fd, 0);
693
    }
694
    else if (g_interface_type == WO_LOCAL) {
695
	char spath[64] = "";
696
	char * path = spath;
697
	if (arg != NULL && g_strlen(arg) > 0) {
698
	  path = arg;
699
	}
700
	else if (intsockname != NULL && g_strlen(intsockname) > 0) {
701
	  g_snprintf(spath, sizeof(spath), "/tmp/%s", intsockname);
702
	  path = spath;
703
	}
704
	if (g_file_exist(path)) {
705
	  g_file_delete(path);
706
	}
707
	if (path != NULL && g_strlen(path) > 0) {
708
	  tpath = g_strdup(path);
709
	}
710
    }
711
    else if (g_interface_type == WO_INET) {
712
      char * port = "7712";
713
      if (arg != NULL && g_strlen((char *)arg) > 0) {
714
	port = arg;
715
      }
716
      fd = g_tcp_socket();
717
      g_tcp_set_non_blocking(fd);
718
      g_tcp_bind_flags(fd, port, AI_ADDRCONFIG | AI_PASSIVE);
719
    }
720
    else {
721
      SAY("ERROR: g_interface_type = %d",g_interface_type);
722
    }
723
    g_trans = trans_create(g_trans_socket_type, MAX_STREAM, MAX_STREAM);
724
    g_trans->trans_data_in = inpipe_data_in;
725
    g_trans->callback_data = NULL;
726
    g_trans->header_size = 0;
727
    lres = trans_listen(g_trans, tpath);
728
    fd = g_trans->sck;
729
    g_tcp_set_non_blocking(fd);
730
    while (!ready) {
731
      g_obj_wait(&fd, 1, NULL, 0, 0);
732
      if (g_is_wait_obj_set(fd)) {
733
	fd = g_tcp_accept(g_trans->sck);
734
	if (fd > -1) {
735
	  ready = 1;
736
	}
737
      }
738
    }
739
    g_trans->sck = fd;
740
    g_trans->type1 = 2;
741
    g_trans->ready = 1;
742
    g_trans->running = 1;
743
    TC_BARR_WAIT(barr_thread);
744
    TC_BARR_WAIT(barr_loop);
745
    while (g_trans == NULL || g_trans->ready < 1 || g_trans->running < 1 || g_trans->sck < 0 || g_trans->trans_data_in == NULL) {
746
      g_sleep(400);
747
    }
748
    if (g_trans == NULL || g_trans->ready < 1 || g_trans->running < 1 || g_trans->sck < 0 || g_trans->trans_data_in == NULL) {
749
      SAY("ERROR: not ready");
750
    }
751
    else while (!done) {
752
      tbus objs[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
753
      ptrdiff_t count = 0;
754
      int timeout = -1;
755
      if (g_trans->lock != NULL) {
756
	TC_MUTEX_LOCK(g_trans->lock);
757
	g_trans->locked = 1;
758
	locked = 1;
759
      }
760
      trans_get_wait_objs(g_trans, objs, &count, &timeout);
761
      if (locked) {
762
        g_trans->locked = 0;
763
        TC_MUTEX_UNLOCK(g_trans->lock);
764
        locked = 0;
765
      }
766
      if ((count > 0) && (g_obj_wait(objs, count, 0, 0, timeout) == 0)) {
767
	ptrdiff_t i = 0;
768
	unsigned char is_set = 0;
769
	for (i = 0; i < count; i++) {
770
	  if (g_is_wait_obj_set(objs[i])) {
771
	    is_set = 1;
772
	    break;
773
	  }
774
	}
775
	if (is_set) {
776
	  if (tres = trans_check_wait_objs(g_trans) != 0) {
777
	    SAY("ERROR: trans_check_wait_objs() returned %d", tres);
778
	    done = 1;
779
	  }
780
	  else {
781
	  }
782
	}
783
      }
784
      TC_MUTEX_LOCK(mutex_done);
785
      if (done > 0) {
786
	g_done = done;
787
      }
788
      done = g_done;
789
      TC_MUTEX_UNLOCK(mutex_done);
790
    }
791
792
    TC_MUTEX_LOCK(mutex_done);
793
    g_done = 1;
794
    TC_MUTEX_UNLOCK(mutex_done);
795
796
  end:;
797
    if (locked) {
798
      g_trans->locked = 0;
799
      TC_MUTEX_UNLOCK(g_trans->lock);
800
      locked = 0;
801
    }
802
    TC_THREAD_EXIT(NULL);
803
    return rv;
804
}
805
806
static void * APP_CC outpipe_loop(void * arg) {
807
    void * rv = (void *)NULL;
808
    unsigned char done = 0;
809
    unsigned char loop_done = 0;
810
    tbus fd = -1;
811
    TC_BARR_WAIT(barr_thread);
812
    while (!done) {
813
      unsigned char cont = 0;
814
      stream_list_t * entry = (stream_list_t *)NULL;
815
      struct stream * s = (struct stream *)NULL;
816
      int cnt = 0;
817
      TC_MUTEX_LOCK(mutex_ilist);
818
      if (!loop_done) {
819
	TC_BARR_WAIT(barr_loop);
820
	loop_done = 1;
821
	if (g_trans_socket_type == WO_FIFO || g_trans_socket_type == 0) {
822
	  if (g_trans != NULL && g_trans->sck_out > -1) {
823
	    fd = g_trans->sck_out;
824
	  }
825
	  else {
826
	    if (!g_file_exist(outpipepath)) {
827
	      g_create_fifo(outpipepath);
828
	    }
829
	    fd = open(outpipepath, O_WRONLY | O_SYNC);
830
	  }
831
	}
832
	else if (g_trans_socket_type == WO_LOCAL || g_trans_socket_type == WO_INET) {
833
	  if (g_trans != NULL && g_trans->sck > -1) {
834
	    fd = g_trans->sck;
835
	  }
836
	}
837
      }
838
      if (ilist_count < 1) {
839
	g_ilist_waiting++;
840
	TC_COND_WAIT(cond_ilist, mutex_ilist);
841
	g_ilist_waiting--;
842
	if (g_ilist_triggered < 1) {
843
	  cont = 1;
844
	}
845
	g_ilist_triggered = 0;
846
      }
847
      TC_MUTEX_UNLOCK(mutex_ilist);
848
      if (cont > 0) {
849
	continue;
850
      }
851
      TC_MUTEX_LOCK(mutex_ilist);
852
      entry = NULL;
853
      if (ilist_count > 0) {
854
	SQ_DEQ(ilist, &entry);
855
	ilist_count--;
856
      }
857
      if (entry == NULL) {
858
	TC_MUTEX_UNLOCK(mutex_ilist);
859
	SAY("deq'd entry is NULL");
860
      }
861
      else {
862
	size_t len = 0;
863
	TC_MUTEX_UNLOCK(mutex_ilist);
864
	s = entry->s;
865
	len = (s == NULL || s->data == NULL || s->p == NULL || s->end == NULL || s->p < s->data || s->end <= s->p || s->size < 1 || (s->end - s->data) > s->size || (s->end - s->p) > s->size) ? 0 : (s->end - s->p);
866
	if (fd > -1 && len > 0) {
867
	  tbus objs[1] = { -1 };
868
	  if (g_trans != NULL) {
869
	    unsigned char locked = 0;
870
	    struct stream * ls = (struct stream *)NULL;
871
	    if (g_trans->lock != NULL) {
872
	      TC_MUTEX_LOCK(g_trans->lock);
873
	      g_trans->locked = 1;
874
	      locked = 1;
875
	    }
876
	    ls = trans_get_out_s(g_trans, MAX_STREAM);
877
	    if (((ls->end + len) - ls->data) <= MAX_STREAM) {
878
	      out_uint8a(ls, s->data, len);
879
	      s_mark_end(ls);
880
	      trans_force_write(g_trans);
881
	    }
882
	    if (locked) {
883
	      g_trans->locked = 0;
884
	      TC_MUTEX_UNLOCK(g_trans->lock);
885
	      locked = 0;
886
	    }
887
	  }
888
	  else {
889
	    if (g_trans_socket_type == WO_FIFO || g_trans_socket_type == 0) {
890
	      g_fifo_write(fd, s->data, len);
891
	    }
892
	    else if (g_trans_socket_type == WO_LOCAL || g_trans_socket_type == WO_INET) {
893
	      g_tcp_send_force(fd, s->data, len, 0);
894
	    }
895
	  }
896
	}
897
	if (s != NULL && s->data != NULL) {
898
	  free_stream(s);
899
	  s = (struct stream *)NULL;
900
	}
901
      }
902
      TC_MUTEX_UNLOCK(mutex_ilist);
903
      if (entry != NULL) {
904
	g_free(entry);
905
	entry = (stream_list_t *)NULL;
906
      }
907
      TC_MUTEX_LOCK(mutex_done);
908
      done = g_done;
909
      TC_MUTEX_UNLOCK(mutex_done);
910
    }
911
    if ((g_trans_socket_type == WO_FIFO || g_trans_socket_type == 0) && (fd > -1)) {
912
      g_file_close(fd);
913
      fd = -1;
914
    }
915
  end:;
916
    TC_THREAD_EXIT(NULL);
917
    return rv;
918
}
919
920
static size_t APP_CC inpipe_data_in(struct trans * chan) {
921
    size_t rv = 0;
922
    tbus id = -1;
923
924
    if (chan == NULL) {
925
      SAY("ERROR: chan is NULL");
926
    }
927
    else if (chan->sck < 0) {
928
      SAY("ERROR: socket is invalid");
929
    }
930
    else if (g_done > 0) {
931
      SAY("DEBUG: g_done is true");
932
    }
933
    else {
934
      unsigned char done = 0;
935
      while (id < 0) {
936
	TC_MUTEX_LOCK(mutex_id);
937
	if (g_channel_id > -1) {
938
	  id = g_channel_id;
939
	  TC_MUTEX_UNLOCK(mutex_id);
940
	  break;
941
	}
942
	else {
943
	  const uint64_t tsec = 300;
944
	  TC_MUTEX_UNLOCK(mutex_id);
945
	  g_sleep(tsec);
946
	}
947
      }
948
      TC_MUTEX_LOCK(mutex_done);
949
      done = g_done;
950
      TC_MUTEX_UNLOCK(mutex_done);
951
      if (done < 1) {
952
	handle_data(id, chan->sck);
953
      }
954
    }
955
956
  end:;
957
    return rv;
958
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/dynamic/xrdp_drdynvc_interface.h (+51 lines)
Line 0    Link Here 
1
#if !defined(XRDP_DRDYNVC_INTERFACE_H)
2
#define	XRDP_DRDYNVC_INTERFACE_H
3
4
#include <errno.h>
5
#include <netdb.h>
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <stdint.h>
9
#include <string.h>
10
#include <unistd.h>
11
#include <netinet/in.h>
12
#include <sys/types.h>
13
#include <sys/socket.h>
14
15
#include "defines.h"
16
#include "arch.h"
17
#include "crc32.h"
18
#include "parse.h"
19
#include "os_calls.h"
20
#include "rdpdr.h"
21
#include "rdpdr_methods.h"
22
#include "stream_list.h"
23
#include "thread_calls.h"
24
#include "thread_macros.h"
25
#include "trans.h"
26
#include "drdynvc_defs.h"
27
28
#if !defined(SAY)
29
#define	SAY(...) {						\
30
	char cbuf[4096];					\
31
	g_memset(cbuf,0,sizeof(cbuf));				\
32
	g_snprintf(cbuf,sizeof(cbuf),__VA_ARGS__);		\
33
	TC_MUTEX_LOCK(mutex_say);				\
34
	g_writeln("[%s() @ line %d]: %s", __func__, __LINE__, cbuf);	\
35
	TC_MUTEX_UNLOCK(mutex_say);				\
36
}
37
#endif
38
39
#if !defined(TC_COND_REINIT)
40
#define TC_COND_REINIT(x) {					\
41
	tc_t	tattr;						\
42
	tc_p	pattr = &tattr;					\
43
	g_memset(pattr,0,sizeof(tc_t));				\
44
	g_memset(x, 0, sizeof(tc_t));				\
45
	TC_CONDATTR_INIT(pattr);				\
46
	TC_CONDATTR_SETPSHARED(pattr, TC_PROCESS_SHARED);	\
47
	TC_COND_CREATE(x, pattr);				\
48
}
49
#endif
50
51
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/dynamic/xrdp_rdpeai.c (+1452 lines)
Line 0    Link Here 
1
#include "xrdp_rdpeai.h"
2
#include "stream_list.h"
3
#include "dbg.h"
4
5
#include <glob.h>
6
#include <pulse/simple.h>
7
8
static volatile unsigned char	g_is_child = 0;
9
static void *			g_pa_args[2] = { NULL, NULL };
10
11
static tc_t			g_chan_thread;
12
static tc_p			thread_chan = &g_chan_thread;
13
static tc_t			g_pa_thread;
14
static tc_p			thread_pa = &g_pa_thread;
15
16
static tc_t			g_done_mutex = TC_MUTEX_INITIALIZER;
17
static tc_p			mutex_done = &g_done_mutex;
18
static tc_t			g_trans_mutex = TC_MUTEX_INITIALIZER;
19
static tc_p			mutex_trans = &g_trans_mutex;
20
static tc_t			g_pa_trans_mutex = TC_MUTEX_INITIALIZER;
21
static tc_p			mutex_pa_trans = &g_pa_trans_mutex;
22
static tc_t			g_formats_mutex = TC_MUTEX_INITIALIZER;
23
static tc_p			mutex_formats = &g_formats_mutex;
24
static tc_t			g_pending_mutex = TC_MUTEX_INITIALIZER;
25
static tc_p			mutex_pending = &g_pending_mutex;
26
static tc_t			g_pending_cond;
27
static tc_p			cond_pending = &g_pending_cond;
28
static tc_t			g_pa_mutex = TC_MUTEX_INITIALIZER;
29
static tc_p			mutex_pa = &g_pa_mutex;
30
static tc_t			g_pa_cond;
31
static tc_p			cond_pa = &g_pa_cond;
32
static tc_t			g_open_mutex = TC_MUTEX_INITIALIZER;
33
static tc_p			mutex_open = &g_open_mutex;
34
static tc_t			g_open_cond;
35
static tc_p			cond_open = &g_open_cond;
36
37
static tc_t			g_thread_barr;
38
static tc_p			barr_thread = &g_thread_barr;
39
static tc_t			g_version_barr;
40
static tc_p			barr_version = &g_version_barr;
41
static tc_t			g_formats_barr;
42
static tc_p			barr_formats = &g_formats_barr;
43
static tc_t			g_open_barr;
44
static tc_p			barr_open = &g_open_barr;
45
static tc_t			g_misc_barr;
46
static tc_p			barr_misc = &g_misc_barr;
47
48
static const char		sockpath[]	= "/tmp/.audio_input_socket";
49
static const char		inpipepath[]	= "/tmp/audio_input_inpipe";
50
static const char		outpipepath[]	= "/tmp/audio_input_outpipe";
51
52
static volatile unsigned char	g_done = 0;
53
static volatile unsigned char	g_version_done = 0;
54
static volatile unsigned char	g_formats_done = 0;
55
static volatile unsigned char	g_misc_done = 0;
56
static volatile unsigned char	g_open = 0;
57
static volatile unsigned int	g_open_pending = 0;
58
static volatile unsigned int	g_open_waiting = 0;
59
static volatile unsigned char	g_pending = 0;
60
static volatile unsigned int	g_pending_waiting = 0;
61
static volatile unsigned int	g_pa_waiting = 0;
62
static volatile ptrdiff_t	g_pa_count = 0;
63
static rdpeai_interface_t	g_interface_type = RDPEAI_SOCKET;
64
65
static volatile unsigned char	g_sound_up = 0;
66
67
static stream_list_t *		ilist = (stream_list_t *)NULL;
68
static stream_list_t *		olist = (stream_list_t *)NULL;
69
static volatile int		ilist_count = 0;
70
static volatile int		olist_count = 0;
71
72
static struct stream *		g_ins = (struct stream *)NULL;
73
static struct stream *		g_pa_stream = (struct stream *)NULL;
74
static tbus			g_fd_in = -1;
75
static tbus			g_fd_out = -1;
76
static tbus			g_fd_log = -1;
77
static int			g_uniqid = 0;
78
static volatile tbus		g_channel_id = -1;
79
80
static const unsigned int	g_trans_socket_type = WO_LOCAL;
81
static struct trans *		g_trans = (struct trans *)NULL;
82
static int			dynamic_channel_id = -1;
83
84
static struct trans *		g_pa_trans = (struct trans *)NULL;
85
86
static size_t			g_client_format_count = 0;
87
static ptrdiff_t		g_client_format_index = -1;
88
static AUDIO_FORMAT_REC *	g_client_formats = (AUDIO_FORMAT_REC *)NULL;
89
static AUDIO_FORMAT_REC *	g_audio_format = (AUDIO_FORMAT_REC *)NULL;
90
91
static AUDIO_FORMAT_REC rdpeai_audio_formats[] = RDPEAI_FORMATS_DEFAULT;
92
93
#define	NUM_THREADS	2
94
95
static tbus			g_pfd = -1;
96
97
98
int		APP_CC		main(int, char * []);
99
static tbus	APP_CC		connect_transport(tbus *, tbus *, const char *, const char *, const char *, const char *);
100
static tbus	APP_CC		launch_child(void);
101
static int	APP_CC		handle_initialization(struct trans *);
102
static int	APP_CC		handle_open(struct trans *);
103
static int	APP_CC		handle_finish(struct trans *);
104
static int	APP_CC		handle_formats(struct trans *);
105
static int	APP_CC		launch_threads(struct trans *);
106
static size_t	APP_CC		chan_data_in(struct trans *);
107
static void *	APP_CC		chan_loop(void *);
108
static int	APP_CC		launch_pa(pa_simple **);
109
static int	APP_CC		stop_pa(pa_simple **);
110
static void *	APP_CC		pa_output_loop(void *);
111
static size_t	APP_CC		pa_data_in(struct trans *);
112
static int	APP_CC		sound_get_pulseaudio_server(const char **);
113
114
115
/* PulseAudio */
116
#define SPEC_PCM		{ .format = PA_SAMPLE_S16LE,	.rate = 44100,	.channels = 2 }; 
117
#define SPEC_PCM_MONO		{ .format = PA_SAMPLE_S16LE,	.rate = 44100,	.channels = 1 };
118
#define	SPEC_ULAW		{ .format = PA_SAMPLE_ULAW,	.rate = 44100,	.channels = 2, }
119
#define	SPEC_ULAW_MONO		{ .format = PA_SAMPLE_ULAW,	.rate = 44100,	.channels = 1, }
120
#define	SPEC_ULAW_LOW		{ .format = PA_SAMPLE_ULAW,	.rate = 11025,	.channels = 2, }
121
#define	SPEC_ALAW		{ .format = PA_SAMPLE_ALAW,	.rate = 44100,	.channels = 2, }
122
#define	SPEC_ALAW_MONO		{ .format = PA_SAMPLE_ALAW,	.rate = 44100,	.channels = 1, }
123
#define	SPEC_IMA_ADPCM		SPEC_PCM
124
static pa_sample_spec		sample_spec = SPEC_ULAW_LOW;
125
static pa_simple *		g_pa = (pa_simple *)NULL;
126
127
128
129
int APP_CC main(int argc, char * argv[]) {
130
    int rv = 0;
131
    tbus fd_in = -1;
132
    tbus fd_out = -1;
133
    tbus fd_log = -1;
134
    char * caddr = (char *)NULL;
135
    char * cport = (char *)NULL;
136
    char * oaddr = (char *)NULL;
137
    char * oport = (char *)NULL;
138
    unsigned char done = 0;
139
140
    make_stream(g_ins);
141
    init_stream(g_ins, MAX_STREAM);
142
143
    make_stream(g_pa_stream);
144
    init_stream(g_pa_stream, MAX_STREAM);
145
146
    {
147
      tc_t lattr;
148
      tc_p attr = &lattr;
149
      g_memset(attr,0,sizeof(tc_t));
150
      TC_CONDATTR_INIT(attr);
151
      TC_COND_CREATE(cond_pending, attr);
152
      TC_COND_CREATE(cond_open, attr);
153
      TC_COND_CREATE(cond_pa, attr);
154
    }
155
    {
156
      tc_t lattr;
157
      tc_p attr = &lattr;
158
      g_memset(attr,0,sizeof(tc_t));
159
      TC_MUTATTR_INIT(attr);
160
      TC_MUTATTR_SETTYPE(attr, TC_MUTEX_ERRORCHECK);
161
      TC_MUTEX_INIT(mutex_pending, attr);
162
      TC_MUTEX_INIT(mutex_open, attr);
163
      TC_MUTEX_INIT(mutex_pa, attr);
164
      TC_MUTEX_INIT(mutex_done, attr);
165
      TC_MUTEX_INIT(mutex_trans, attr);
166
      TC_MUTEX_INIT(mutex_formats, attr);
167
      TC_MUTEX_INIT(mutex_pa_trans, attr);
168
    }
169
170
    g_pfd = launch_child();
171
    if (g_pfd < 0 || g_is_child > 0) {
172
      rv = 0;
173
      goto end;
174
    }
175
176
    if (argc > 1 && argv[1] != NULL && g_strlen(argv[1]) > 0) {
177
      char * cpos = (char *)NULL;
178
      cpos = g_strchr(argv[1],':');
179
      if (cpos == NULL) {
180
	caddr = g_strndup(argv[1],64);
181
      }
182
      else {
183
	cport = g_strndup(cpos,10);
184
	caddr = g_strndup(argv[1],(cpos - argv[1]));
185
      }
186
      if (cport == NULL || g_strlen(cport) == 0) {
187
	g_interface_type = RDPEAI_SOCKET;
188
      }
189
      else {
190
	g_interface_type = RDPEAI_INET;
191
      }
192
    }
193
    if (argc > 2 && argv[2] != NULL && g_strlen(argv[2]) > 0) {
194
      char * cpos = (char *)NULL;
195
      cpos = g_strchr(argv[2],':');
196
      if (cpos == NULL) {
197
	oaddr = g_strndup(argv[2],64);
198
      }
199
      else {
200
	oport = g_strndup(cpos,10);
201
	oaddr = g_strndup(argv[2],(cpos - argv[2]));
202
      }
203
    }
204
    if (argc < 2) {
205
      g_fd_in = STDIN_FILENO;
206
      g_fd_out = STDOUT_FILENO;
207
      fd_in = g_fd_in;
208
      fd_out = g_fd_out;
209
      g_interface_type = 0;
210
    }
211
    if (connect_transport(&fd_in, &fd_out, caddr, cport, oaddr, oport) > -1) {
212
      g_fd_in = fd_in;
213
      g_fd_out = fd_out;
214
    }
215
    else {
216
      SAY("failed to establish connection (rv = %d, fd_out = %d)", rv, fd_out);
217
      rv = -1;
218
      g_done = 1;
219
      g_fd_out = -1;
220
      goto end;
221
    }
222
223
    g_memset(barr_thread, 0, sizeof(tc_t));
224
    TC_BARR_INIT(barr_thread, (NUM_THREADS + 1));
225
    g_memset(barr_version, 0, sizeof(tc_t));
226
    TC_BARR_INIT(barr_version, NUM_THREADS);
227
    g_memset(barr_formats, 0, sizeof(tc_t));
228
    TC_BARR_INIT(barr_formats, NUM_THREADS);
229
    g_memset(barr_misc, 0, sizeof(tc_t));
230
    TC_BARR_INIT(barr_misc, NUM_THREADS);
231
    g_memset(barr_open, 0, sizeof(tc_t));
232
    TC_BARR_INIT(barr_open, NUM_THREADS);
233
234
    launch_threads(g_trans);
235
    TC_BARR_WAIT(barr_thread);
236
237
    TC_MUTEX_LOCK(mutex_trans);
238
    handle_initialization(g_trans);
239
    TC_MUTEX_UNLOCK(mutex_trans);
240
    TC_BARR_WAIT(barr_version);
241
242
    TC_MUTEX_LOCK(mutex_trans);
243
    handle_formats(g_trans);
244
    TC_MUTEX_UNLOCK(mutex_trans);
245
    TC_BARR_WAIT(barr_formats);
246
247
    TC_MUTEX_LOCK(mutex_trans);
248
    handle_open(g_trans);
249
    TC_MUTEX_UNLOCK(mutex_trans);
250
    TC_BARR_WAIT(barr_open);
251
252
    TC_BARR_WAIT(barr_misc);
253
254
    TC_MUTEX_LOCK(mutex_trans);
255
    handle_finish(g_trans);
256
    TC_MUTEX_UNLOCK(mutex_trans);
257
258
    stop_pa(&g_pa);
259
260
    TC_THREAD_JOIN(thread_pa->thread, NULL);
261
    TC_THREAD_JOIN(thread_chan->thread, NULL);
262
263
  end:;
264
    if (g_fd_log > -1) {
265
      g_file_close(g_fd_log);
266
    }
267
    g_sleep(200);
268
    return rv;
269
}
270
271
272
static int APP_CC launch_pa(pa_simple ** s) {
273
    int rv = 0;
274
    const char * server = (const char *)NULL;
275
    if (s == NULL) {
276
	SAY("ERROR: *s is NULL");
277
	rv = -1;
278
	goto end;
279
    }
280
    else {
281
	int error = 0;
282
	//sound_get_pulseaudio_server(&server);
283
	*s = pa_simple_new(
284
		server,			/* const char *		server,		*/
285
		"xrdp_sndin",		/* const char *		name,		*/
286
		PA_STREAM_PLAYBACK,	/* pa_stream_direction_t dir,		*/
287
		NULL,			/* const char *		dev,		*/
288
		"sndin",		/* const char *		stream_name,	*/
289
		&sample_spec,		/* const pa_sample_spec * ss,		*/
290
		NULL,			/* const pa_channel_map * map,		*/
291
		NULL,			/* const pa_buffer_attr * attr,		*/
292
		&error			/* int *		error		*/
293
	);
294
	if (*s == NULL) {
295
		SAY("ERROR: pa_simple_new() failed [error = %d]",error);
296
		rv = -1;
297
		goto end;
298
	}
299
    }
300
  end:;
301
    return rv;
302
}
303
304
static int APP_CC stop_pa(pa_simple ** s) {
305
    int rv = 0;
306
    if (s != NULL && *s != NULL) {
307
	pa_simple_free(*s);
308
    }
309
    return rv;
310
}
311
312
313
static int APP_CC launch_threads(struct trans * chan) {
314
    int rv = 0;
315
    tc_t attr;
316
    tc_p pattr = &attr;
317
318
    g_memset(pattr, 0, sizeof(tc_t));
319
    TC_THREADATTR_INIT(pattr);
320
    TC_THREADATTR_SETDETACHSTATE(pattr, TC_CREATE_JOINABLE);
321
    TC_THREAD_INIT_FULL(&(thread_chan->thread), &(pattr->threadattr), &chan_loop, chan);
322
    TC_THREAD_INIT_FULL(&(thread_pa->thread), &(pattr->threadattr), &pa_output_loop, g_pa);
323
324
  end:;
325
    return rv;
326
}
327
328
static tbus APP_CC connect_transport(tbus * fd_in, tbus * fd_out, const char * iaddress, const char * iport, const char * oaddress, const char * oport) {
329
    tbus rv = -1;
330
    unsigned char is_local = 0;
331
    unsigned char is_fifo = 0;
332
    unsigned char is_stdio = 0;
333
    unsigned char locked = 0;
334
    char * addr = "localhost";
335
    char * port = "7712";
336
337
    TC_MUTEX_LOCK(mutex_trans);
338
339
    if ((iaddress == NULL || g_strlen(iaddress) == 0) && (iport == NULL || g_strlen(iport) == 0)) {
340
      is_stdio = 1;
341
      addr = (char *)NULL;
342
      port = (char *)NULL;
343
      g_interface_type == 0;
344
    }
345
    else {
346
      if (iaddress != NULL && g_strlen(iaddress) > 0) {
347
	addr = (char *)iaddress;
348
      }
349
      if (iport != NULL && g_strlen(iport) > 0) {
350
	port = (char *)iport;
351
      }
352
    }
353
    if (g_interface_type == RDPEAI_FIFO) {
354
	is_fifo = 1;
355
    }
356
    else {
357
	is_fifo = 0;
358
    }
359
    if (addr != NULL && g_strlen(addr) > 0 && g_strchr(addr, '/') != NULL) {
360
	is_local = 1;
361
    }
362
    else {
363
	is_local = 0;
364
    }
365
    if (is_stdio) {
366
      SAY("(using stdout)");
367
      g_trans = trans_create(0, MAX_STREAM, MAX_STREAM);
368
      if (g_trans != NULL && g_trans->lock != NULL) {
369
	TC_MUTEX_LOCK(g_trans->lock);
370
	g_trans->locked = 1;
371
	locked = 1;
372
      }
373
      trans_connect(g_trans, NULL, NULL, 0);
374
      *fd_in = g_trans->sck;
375
      *fd_out = g_trans->sck_out;
376
    }
377
    else if (is_fifo) {
378
      SAY("(using fifo)");
379
      if (addr == NULL || g_strlen(addr) < 1) {
380
	SAY("ERROR: path is empty for fifo");
381
	*fd_in = -1;
382
	*fd_out = -1;
383
	rv = -1;
384
      }
385
      else if (*fd_out = g_fifo_open(addr) < 1) {
386
	SAY("ERROR: g_fifo_open(\"%s\") failed",addr);
387
	*fd_in = -2;
388
	*fd_out = -2;
389
	rv = -2;
390
      }
391
      if (oaddress == NULL || g_strlen(oaddress) < 1) {
392
	SAY("ERROR: path is empty for fifo");
393
	*fd_in = -1;
394
	*fd_out = -1;
395
	rv = -1;
396
      }
397
      else if (*fd_out = g_fifo_open(oaddress) < 1) {
398
	SAY("ERROR: g_fifo_open(\"%s\") failed",oaddress);
399
	*fd_in = -2;
400
	*fd_out = -2;
401
	rv = -2;
402
      }
403
      g_trans = trans_create(WO_FIFO, MAX_STREAM, MAX_STREAM);
404
      if (g_trans != NULL && g_trans->lock != NULL) {
405
	TC_MUTEX_LOCK(g_trans->lock);
406
	g_trans->locked = 1;
407
	locked = 1;
408
      }
409
      trans_attach(g_trans, *fd_out);
410
      g_trans->sck = *fd_in;
411
      g_trans->sck_out = *fd_out;
412
    }
413
    else if (is_local) {
414
      SAY("(using local socket)");
415
      if ((*fd_out = g_tcp_local_socket()) < 1) {
416
	*fd_out = -2;
417
	rv = -2;
418
      }
419
      else {
420
	rv = g_tcp_local_connect(*fd_out, addr);
421
      }
422
      g_trans = trans_create(WO_LOCAL, MAX_STREAM, MAX_STREAM);
423
      if (g_trans != NULL && g_trans->lock != NULL) {
424
	TC_MUTEX_LOCK(g_trans->lock);
425
	g_trans->locked = 1;
426
	locked = 1;
427
      }
428
      trans_attach(g_trans, *fd_out);
429
      g_tcp_set_non_blocking(g_trans->sck);
430
    }
431
    else {
432
      if ((*fd_out = g_tcp_socket()) < 1) {
433
	rv = -2;
434
      }
435
      else {
436
	rv = g_tcp_connect(*fd_out, addr, port);
437
      }
438
      g_trans = trans_create(WO_INET, MAX_STREAM, MAX_STREAM);
439
      if (g_trans != NULL && g_trans->lock != NULL) {
440
	TC_MUTEX_LOCK(g_trans->lock);
441
	g_trans->locked = 1;
442
	locked = 1;
443
      }
444
      trans_attach(g_trans, *fd_in);
445
      g_tcp_set_non_blocking(g_trans->sck);
446
    }
447
448
    if (g_trans != NULL) {
449
      g_trans->trans_data_in = chan_data_in;
450
      g_trans->callback_data = g_trans;
451
      g_trans->header_size = 0;
452
      g_trans->ready = 1;
453
      g_trans->running = 1;
454
    }
455
456
    rv = *fd_out;
457
458
  end:;
459
    if (locked) {
460
      g_trans->locked = 0;
461
      TC_MUTEX_UNLOCK(g_trans->lock);
462
      locked = 0;
463
    }
464
    TC_MUTEX_UNLOCK(mutex_trans);
465
    return rv;
466
}
467
468
static void * APP_CC chan_loop(void * arg) {
469
    void * rv = (void *)NULL;
470
    struct trans * chan = (struct trans *)NULL;
471
    int tres = 0;
472
    unsigned char done = 0;
473
    unsigned char barrier_done = 0;
474
    SAY("called");
475
    if (arg != NULL) {
476
      chan = (struct trans *)arg;
477
    }
478
    if (chan == NULL) {
479
      TC_MUTEX_LOCK(mutex_trans);
480
      chan = g_trans;
481
      TC_MUTEX_UNLOCK(mutex_trans);
482
    }
483
    if (chan == NULL) {
484
      SAY("ERROR: chan is NULL");
485
    }
486
    else while (!done) {
487
      tbus objs[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
488
      ptrdiff_t count = 0;
489
      int timeout = -1;
490
      unsigned char locked = 0;
491
      if (!barrier_done) {
492
        TC_BARR_WAIT(barr_thread);
493
	barrier_done = 1;
494
      }
495
      if (chan->lock != NULL) {
496
	TC_MUTEX_LOCK(chan->lock);
497
	chan->locked = 1;
498
	locked = 1;
499
      }
500
      TC_MUTEX_LOCK(mutex_trans);
501
      trans_get_wait_objs(chan, objs, &count, &timeout);
502
      if (locked) {
503
	chan->locked = 0;
504
	TC_MUTEX_UNLOCK(chan->lock);
505
	locked = 0;
506
      }
507
      TC_MUTEX_UNLOCK(mutex_trans);
508
      if ((count > 0) && (g_obj_wait(objs, count, 0, 0, timeout) == 0)) {
509
	ptrdiff_t i = 0;
510
	unsigned char is_set = 0;
511
	//SAY("count = %d",count);
512
	for (i = 0; i < count; i++) {
513
	  if (g_is_wait_obj_set(objs[i])) {
514
	    is_set = 1;
515
	    break;
516
	  }
517
	}
518
	TC_MUTEX_LOCK(mutex_trans);
519
	TC_MUTEX_LOCK(chan->lock);
520
	if ((is_set > 0) && (tres = trans_check_wait_objs(chan)) != 0) {
521
	  SAY("ERROR: trans_check_wait_objs() returned %d", tres);
522
	  done = 1;
523
	}
524
	TC_MUTEX_UNLOCK(chan->lock);
525
	TC_MUTEX_UNLOCK(mutex_trans);
526
      }
527
      TC_MUTEX_LOCK(mutex_done);
528
      if (done > 0) {
529
	g_done = done;
530
      }
531
      done = g_done;
532
      TC_MUTEX_UNLOCK(mutex_done);
533
    }
534
  end:;
535
    TC_BARR_WAIT(barr_misc);
536
    SAY("done.");
537
    TC_THREAD_EXIT(NULL);
538
    return rv;
539
}
540
541
static size_t APP_CC chan_data_in(struct trans * chan) {
542
    size_t rv = 0;
543
    unsigned char locked = 0;
544
    //SAY("DEBUG: called");
545
    if (chan == NULL) {
546
      SAY("ERROR: chan is NULL");
547
    }
548
    else {
549
      ptrdiff_t len = 0;
550
      struct stream * s = (struct stream *)NULL;
551
      if (0 && chan->lock != NULL) {
552
	TC_MUTEX_LOCK(chan->lock);
553
	chan->locked = 1;
554
	locked = 1;
555
      }
556
      trans_force_read(chan, 3);
557
      s = trans_get_in_s(chan);
558
      if (s == NULL) {
559
	SAY("ERROR: input stream is NULL");
560
      }
561
      else {
562
        BYTE opcode = 0x00;
563
	in_uint8s(s, 2)
564
	in_uint8(s, opcode);
565
	switch (opcode) {
566
	  case CMSG_SNDIN_VERSION:
567
	    SAY(" ** MSG_SNDIN_VERSION");
568
	    {
569
		trans_force_read(chan, 4);
570
		g_reset_wait_obj(chan->sck);
571
		if (!g_version_done) {
572
		  g_version_done = 1;
573
		  TC_BARR_WAIT(barr_version);
574
		}
575
	    }
576
	    break;
577
	  case CMSG_SNDIN_FORMATS:
578
	    SAY(" ** MSG_SNDIN_FORMATS");
579
	    {
580
		DWORD		count = 0;
581
		DWORD		size = 0;
582
		ptrdiff_t	rem = (MAX_STREAM - 8);
583
		struct stream *	ls = (struct stream *)NULL;
584
		void *		tp = (void *)NULL;
585
		trans_force_read(chan, 8);
586
		in_uint32_le(s, count);
587
		in_uint32_le(s, size);
588
		if (size > 9) {
589
		  const size_t relsize = (const size_t)(size - 9);
590
		  assert(count > 0);
591
		  tp = (void *)(s->p);
592
		  trans_force_read(chan, relsize);
593
		  rem -= ((MAX_STREAM >= relsize) ? relsize : 0);
594
		  ls = (struct stream *)g_malloc(sizeof(struct stream), 1);
595
		  g_memcpy(ls, s, sizeof(struct stream));
596
		  s->data = (char *)g_malloc(s->size, 1);
597
		  s->p = s->data + (ls->p - ls->data);
598
		  s->end = s->data + (ls->end - ls->data);
599
		}
600
		if (rem > 0) {
601
		  trans_read(chan, MIN(rem, (s->size - (s->p - s->data))));
602
		}
603
		TC_MUTEX_LOCK(mutex_pending);
604
		if (g_pending > 0) {
605
		  g_pending = 0;
606
		}
607
		if (g_pending_waiting > 0) {
608
		  if (g_pending_waiting > 1) {
609
		    TC_COND_BROADCAST(cond_pending);
610
		  }
611
		  else {
612
		    TC_COND_SIGNAL(cond_pending);
613
		  }
614
		}
615
		TC_MUTEX_UNLOCK(mutex_pending);
616
		/* Process the sound formats received from the client */
617
		TC_MUTEX_LOCK(mutex_formats);
618
		g_client_format_count = count;
619
		if (g_client_format_count > 0 && tp != NULL) {
620
		  g_client_formats = (AUDIO_FORMAT_REC *)tp;
621
		  g_client_format_index = 0;
622
		  g_audio_format = (AUDIO_FORMAT_REC *)tp;
623
		  assert(g_audio_format == &(g_client_formats[g_client_format_index]));
624
		  SAY("DEBUG: audio format = 0x%8.8x",g_audio_format->wFormatTag);
625
		}
626
		else {
627
		  SAY("ERROR: failed to negotiate a common audio format between the client and server");
628
		}
629
		/* Trigger the "barr_formats" barrier in order to proceed with subsequent operation */
630
		if (g_formats_done < 1) {
631
		  g_formats_done = 1;
632
		  TC_MUTEX_UNLOCK(mutex_formats);
633
		  TC_BARR_WAIT(barr_formats);
634
		}
635
		else {
636
		  TC_MUTEX_UNLOCK(mutex_formats);
637
		}
638
	    }
639
	    break;
640
	  case CMSG_SNDIN_OPEN:
641
	    SAY(" ** MSG_SNDIN_OPEN");
642
	    {
643
		SAY("ERROR: invalid opcode (MS-RDPEAI does not permit a client to transmit a MSG_SNDIN_OPEN pdu to the server)");
644
		trans_read(chan, MAX_STREAM);
645
	    }
646
	    break;
647
	  case CMSG_SNDIN_OPEN_REPLY:
648
	    SAY(" ** MSG_SNDIN_OPEN_REPLY");
649
	    {
650
		HRESULT res = 0x00000000;
651
		unsigned char already_opened = 0;
652
		trans_force_read(chan, 4);
653
		in_uint32_le(s, res);
654
		SAY("INFO: Result = 0x%8.8x",res);
655
		TC_MUTEX_LOCK(mutex_open);
656
		if (g_open < 1) {
657
		  already_opened = 0;
658
		}
659
		else {
660
		  already_opened = 1;
661
		}
662
		if (g_open < 1 && g_open_pending > 0) {
663
		  g_open = 1;
664
		  g_open_pending--;
665
		}
666
		if (g_open > 0 && g_open_waiting > 0) {
667
		  if (g_open_waiting > 1) {
668
		    TC_COND_BROADCAST(cond_open);
669
		  }
670
		  else {
671
		    TC_COND_SIGNAL(cond_open);
672
		  }
673
		}
674
		TC_MUTEX_UNLOCK(mutex_open);
675
		if (already_opened < 1) {
676
		  TC_BARR_WAIT(barr_open);
677
		}
678
	    }
679
	    break;
680
	  case CMSG_SNDIN_DATA_INCOMING:
681
	    //SAY(" ** MSG_SNDIN_DATA_INCOMING");
682
	    {
683
		TC_MUTEX_LOCK(mutex_pending);
684
		g_pending++;
685
		TC_MUTEX_UNLOCK(mutex_pending);
686
	    }
687
	    break;
688
	  case CMSG_SNDIN_DATA:
689
	    //SAY(" ** MSG_SNDIN_DATA");
690
	    {
691
		ptrdiff_t llen = 0;
692
		trans_read(chan, MAX_STREAM);
693
		if ((s->end > s->p) && (s->end != NULL) && (s->p != NULL) && ((s->end - s->p) > 0)) {
694
		  llen = (s->end - s->p);
695
		}
696
		TC_MUTEX_LOCK(mutex_pending);
697
		if (g_pending > 0) {
698
		  g_pending--;
699
		}
700
		if (g_pending_waiting > 0) {
701
		  if (g_pending_waiting > 1) {
702
		    TC_COND_BROADCAST(cond_pending);
703
		  }
704
		  else {
705
		    TC_COND_SIGNAL(cond_pending);
706
		  }
707
		}
708
		TC_MUTEX_UNLOCK(mutex_pending);
709
		TC_MUTEX_LOCK(mutex_pa);
710
		if (llen > 0) {
711
		  uint32_t * pnum = (uint32_t *)(g_pa_stream->data);
712
		  if (g_pa_count == 0) {
713
		    g_pa_stream->p = g_pa_stream->end = g_pa_stream->data;
714
		    g_pa_stream->p += 4;
715
		    g_pa_stream->end = g_pa_stream->p;
716
		    *pnum = 0x00000000;
717
		  }
718
		  g_memcpy(g_pa_stream->p, s->p, llen);
719
		  g_pa_stream->p += llen;
720
		  g_pa_stream->end = g_pa_stream->p;
721
		  *pnum += llen;
722
		  g_pa_count++;
723
724
		  if (llen > 0 && g_fd_log > -1) {
725
		    g_file_write(g_fd_log, s->p, llen);
726
		  }
727
728
		  if (*pnum > (MAX_STREAM / 2)) {
729
		    g_pa_stream->p = g_pa_stream->data;
730
		    if (g_pa_trans != NULL && g_pa_trans->sck > -1) {
731
		  	struct stream * ls = (struct stream *)NULL;
732
		  	TC_MUTEX_LOCK(g_pa_trans->lock);
733
		  	g_pa_trans->locked = 1;
734
		  	//ls = trans_get_out_s(g_pa_trans, (*pnum + 4));
735
		  	g_pa_trans->out_s = g_pa_stream;
736
		  	SAY("sending %d bytes to child",*pnum);
737
		  	trans_force_write(g_pa_trans);
738
		  	g_pa_trans->locked = 0;
739
		  	TC_MUTEX_UNLOCK(g_pa_trans->lock);
740
		    }
741
		    g_pa_stream->p = g_pa_stream->data;
742
		    g_pa_count = 0;
743
		    *pnum = 0;
744
		  }
745
		}
746
		if (g_pa_waiting > 0 && g_pa_count > 6) {
747
		  if (g_pa_waiting > 1) {
748
		    TC_COND_BROADCAST(cond_pa);
749
		  }
750
		  else {
751
		    TC_COND_SIGNAL(cond_pa);
752
		  }
753
		}
754
		TC_MUTEX_UNLOCK(mutex_pa);
755
	    }
756
	    break;
757
	  case CMSG_SNDIN_FORMATCHANGE:
758
	    SAY(" ** MSG_SNDIN_FORMATCHANGE");
759
	    {
760
		uint32_t newidx = 0;
761
		if (g_client_format_index > -1 && g_client_format_index < g_client_format_count) {
762
		  newidx = g_client_format_index;
763
		}
764
		trans_force_read(chan, 4);
765
		in_uint32_le(s, newidx);
766
		SAY("received format index = %d", newidx);
767
		if (newidx >= 0 && newidx <= g_client_format_count) {
768
		  g_client_format_index = newidx;
769
		  g_audio_format = (&(g_client_formats[g_client_format_index]));
770
		}
771
		SAY("new format index = %d (wFormatTag = 0x%8.8x)", newidx, g_client_formats[g_client_format_index].wFormatTag);
772
	    }
773
	    break;
774
	  default:
775
	    SAY(" ** ERROR: unrecognized instruction (opcode = 0x%8.8x)",opcode);
776
	    break;
777
	}
778
	len = s->end - s->data;
779
	//SAY("(len = %d)",len);
780
	if (len > 0) {
781
	  //g_hexdump_file("/tmp/taskq_hex_RDPEAI_CHAN_DATA_IN.hexdump",(s->data + chan->header_size),len);
782
	}
783
      }
784
    }
785
  end:;
786
    if (locked) {
787
      chan->locked = 0;
788
      TC_MUTEX_UNLOCK(chan->lock);
789
      locked = 0;
790
    }
791
    //SAY("done (g_version_done = %d, g_formats_done = %d).",g_version_done,g_formats_done);
792
    return rv;
793
}
794
795
static int APP_CC handle_initialization(struct trans * chan) {
796
    int			rv = 0;
797
    struct stream *	s = (struct stream *)NULL;
798
    unsigned char	locked = 0;
799
    unsigned char	ready = 0;
800
801
    SAY("called");
802
803
    if (chan == NULL) {
804
      SAY("ERROR: chan is NULL");
805
      rv = -1;
806
      goto end;
807
    }
808
    while (!ready) {
809
      if (chan->lock != NULL) {
810
	TC_MUTEX_LOCK(chan->lock);
811
	chan->locked = 1;
812
	locked = 1;
813
      }
814
      if (chan->ready > 0 && chan->running > 0 && chan->status == 1) {
815
	ready = 1;
816
      }
817
      if (locked) {
818
	chan->locked = 0;
819
	TC_MUTEX_UNLOCK(chan->lock);
820
	locked = 0;
821
      }
822
      if (!ready) {
823
	g_sleep(300);
824
      }
825
    }
826
    if (chan->lock != NULL) {
827
      TC_MUTEX_LOCK(chan->lock);
828
      chan->locked = 1;
829
      locked = 1;
830
    }    
831
    s = trans_get_out_s(chan, MAX_STREAM);
832
    if (s == NULL) {
833
      SAY("ERROR: s is NULL");
834
      rv = -1;
835
      goto end;
836
    }
837
    else {
838
      ptrdiff_t len = 0;
839
      MSG_SNDIN_VERSION * pdu = (MSG_SNDIN_VERSION *)NULL;
840
      pdu = (MSG_SNDIN_VERSION *)g_malloc(sizeof(MSG_SNDIN_VERSION), 1);
841
      if (pdu == NULL) {
842
	SAY("ERROR: pdu is NULL");
843
	goto end;
844
      }
845
      else {
846
	construct_MSG_SNDIN_VERSION(pdu);
847
	send_MSG_SNDIN_VERSION(pdu, s);
848
      }
849
      s_mark_end(s);
850
      len = s->end - s->data;
851
      if (len > 0) {
852
	ptrdiff_t tres = 0;
853
	//g_hexdump_file("/tmp/taskq_hex_MSG_SNDIN_VERSION.hexdump", s->data, len);
854
	if (chan->mode == 3 || chan->mode == 0) {
855
	  SAY("about to call trans_force_write(): (chan->sck_out = %d, len = %d)", chan->sck_out, len);
856
	}
857
	if ((g_interface_type == 0 || g_interface_type == 3) || ((g_interface_type == 1 || g_interface_type == 2) && g_tcp_socket_ok(chan->sck) && g_tcp_can_send(chan->sck, 300))) {
858
	  SAY("about to call trans_force_write(): (chan->sck = %d, chan->sck_out = %d, len = %d)", chan->sck, chan->sck_out, len);
859
	  tres = trans_force_write(chan);
860
	  SAY("trans_force_write() returned (tres = %d)",tres);
861
	}
862
	else {
863
	  SAY("ERROR: unable to send (g_interface_type = %d)", g_interface_type);
864
	}
865
      }
866
      if (pdu != NULL) {
867
	g_free(pdu);
868
	pdu = (MSG_SNDIN_VERSION *)NULL;
869
      }
870
    }
871
872
  end:;
873
    if (locked) {
874
      chan->locked = 0;
875
      TC_MUTEX_UNLOCK(chan->lock);
876
      locked = 0;
877
    }
878
    SAY("done.");
879
    return rv;
880
}
881
882
static int APP_CC handle_formats(struct trans * chan) {
883
    int			rv = 0;
884
    struct stream *	s = (struct stream *)NULL;
885
    unsigned char	locked = 0;
886
    unsigned char	ready = 0;
887
888
    SAY("called");
889
890
    if (chan == NULL) {
891
      SAY("ERROR: chan is NULL");
892
      rv = -1;
893
      goto end;
894
    }
895
    while (!ready) {
896
      if (chan->lock != NULL) {
897
	TC_MUTEX_LOCK(chan->lock);
898
	chan->locked = 1;
899
	locked = 1;
900
      }
901
      if (chan->ready > 0 && chan->running > 0 && chan->status == 1) {
902
	ready = 1;
903
      }
904
      if (locked) {
905
	chan->locked = 0;
906
	TC_MUTEX_UNLOCK(chan->lock);
907
	locked = 0;
908
      }
909
      if (!ready) {
910
	g_sleep(300);
911
      }
912
    }
913
    if (chan->lock != NULL) {
914
      TC_MUTEX_LOCK(chan->lock);
915
      chan->locked = 1;
916
      locked = 1;
917
    }    
918
    s = trans_get_out_s(chan, MAX_STREAM);
919
    if (s == NULL) {
920
      SAY("ERROR: s is NULL");
921
      rv = -1;
922
      goto end;
923
    }
924
    else {
925
      ptrdiff_t len = 0;
926
      MSG_SNDIN_FORMATS * pdu = (MSG_SNDIN_FORMATS *)NULL;
927
      pdu = (MSG_SNDIN_FORMATS *)g_malloc((sizeof(MSG_SNDIN_FORMATS) + (sizeof(AUDIO_FORMAT_REC) * RDPEAI_NUM_FORMATS)), 1);
928
      if (pdu == NULL) {
929
	SAY("ERROR: pdu is NULL");
930
	goto end;
931
      }
932
      else {
933
	ptrdiff_t i = 0;
934
	AUDIO_FORMAT_REC * fmt = (AUDIO_FORMAT_REC *)NULL;
935
	DWORD * pnum = (DWORD *)NULL;
936
	construct_MSG_SNDIN_FORMATS(pdu);
937
	pdu->NumFormats = RDPEAI_NUM_FORMATS;
938
	pnum = (DWORD *)NULL;
939
	pdu->cbSizeFormatsPacket = sizeof(MSG_SNDIN_FORMATS) + (sizeof(AUDIO_FORMAT_REC) * pdu->NumFormats);
940
	for (i = 0; i < pdu->NumFormats; i++) {
941
	  fmt = &(pdu->SoundFormats[i]);
942
	  g_memcpy(fmt, &(rdpeai_audio_formats[i]), sizeof(AUDIO_FORMAT_REC));
943
	}
944
	send_MSG_SNDIN_FORMATS(pdu, s);
945
      }
946
      s_mark_end(s);
947
      len = s->end - s->data;
948
      if (len > 0) {
949
	ptrdiff_t tres = 0;
950
	//g_hexdump_file("/tmp/taskq_hex_MSG_SNDIN_FORMATS.hexdump", s->data, len);
951
	if (chan->mode == 3 || chan->mode == 0) {
952
	  SAY("about to call trans_force_write(): (chan->sck_out = %d, len = %d)", chan->sck_out, len);
953
	}
954
	if ((g_interface_type == 0 || g_interface_type == 3) || ((g_interface_type == 1 || g_interface_type == 2) && g_tcp_socket_ok(chan->sck) && g_tcp_can_send(chan->sck, 300))) {
955
	  SAY("about to call trans_force_write(): (chan->sck = %d, chan->sck_out = %d, len = %d)", chan->sck, chan->sck_out, len);
956
	  tres = trans_force_write(chan);
957
	  SAY("trans_force_write() returned (tres = %d)",tres);
958
	}
959
	else {
960
	  SAY("ERROR: unable to send (g_interface_type = %d)", g_interface_type);
961
	}
962
      }
963
      if (pdu != NULL) {
964
	g_free(pdu);
965
	pdu = (MSG_SNDIN_FORMATS *)NULL;
966
      }
967
    }
968
969
  end:;
970
    if (locked) {
971
      chan->locked = 0;
972
      TC_MUTEX_UNLOCK(chan->lock);
973
      locked = 0;
974
    }
975
    SAY("done.");
976
    return rv;
977
}
978
979
static int APP_CC handle_open(struct trans * chan) {
980
    int	rv = 0;
981
    struct stream *	s = (struct stream *)NULL;
982
    unsigned char	locked = 0;
983
    unsigned char	ready = 0;
984
985
    SAY("called");
986
987
    if (chan == NULL) {
988
      SAY("ERROR: chan is NULL");
989
      rv = -1;
990
      goto end;
991
    }
992
    while (!ready) {
993
      if (chan->lock != NULL) {
994
	TC_MUTEX_LOCK(chan->lock);
995
	chan->locked = 1;
996
	locked = 1;
997
      }
998
      if (chan->ready > 0 && chan->running > 0 && chan->status == 1) {
999
	ready = 1;
1000
      }
1001
      if (locked) {
1002
	chan->locked = 0;
1003
	TC_MUTEX_UNLOCK(chan->lock);
1004
	locked = 0;
1005
      }
1006
      if (!ready) {
1007
	g_sleep(300);
1008
      }
1009
    }
1010
    if (chan->lock != NULL) {
1011
      TC_MUTEX_LOCK(chan->lock);
1012
      chan->locked = 1;
1013
      locked = 1;
1014
    }    
1015
    s = trans_get_out_s(chan, MAX_STREAM);
1016
    if (s == NULL) {
1017
      SAY("ERROR: s is NULL");
1018
      rv = -1;
1019
      goto end;
1020
    }
1021
    else {
1022
      ptrdiff_t len = 0;
1023
      MSG_SNDIN_OPEN * pdu = (MSG_SNDIN_OPEN *)NULL;
1024
      pdu = (MSG_SNDIN_OPEN *)g_malloc(sizeof(MSG_SNDIN_OPEN), 1);
1025
      if (pdu == NULL) {
1026
	SAY("ERROR: pdu is NULL");
1027
	goto end;
1028
      }
1029
      else {
1030
	construct_MSG_SNDIN_OPEN(pdu);
1031
	TC_MUTEX_LOCK(mutex_formats);
1032
	pdu->initialFormat = g_client_format_index + 1;
1033
	pdu->wFormatTag = g_audio_format->wFormatTag;
1034
	pdu->nChannels = g_audio_format->nChannels;
1035
	pdu->nSamplesPerSec = g_audio_format->nSamplesPerSec;
1036
	pdu->nAvgBytesPerSec = g_audio_format->nAvgBytesPerSec;
1037
	pdu->nBlockAlign = g_audio_format->nBlockAlign;
1038
	pdu->wBitsPerSample = g_audio_format->wBitsPerSample;
1039
	pdu->cbSize = g_audio_format->cbSize;
1040
	pdu->FramesPerPacket = 1560;
1041
	TC_MUTEX_UNLOCK(mutex_formats);
1042
	send_MSG_SNDIN_OPEN(pdu, s);
1043
      }
1044
      s_mark_end(s);
1045
      len = s->end - s->data;
1046
      if (len > 0) {
1047
	ptrdiff_t tres = 0;
1048
	//g_hexdump_file("/tmp/taskq_hex_MSG_SNDIN_OPEN.hexdump", s->data, len);
1049
	if (chan->mode == 3 || chan->mode == 0) {
1050
	  SAY("about to call trans_force_write(): (chan->sck_out = %d, len = %d)", chan->sck_out, len);
1051
	}
1052
	if ((g_interface_type == 0 || g_interface_type == 3) || ((g_interface_type == 1 || g_interface_type == 2) && g_tcp_socket_ok(chan->sck) && g_tcp_can_send(chan->sck, 300))) {
1053
	  TC_MUTEX_LOCK(mutex_open);
1054
	  assert(g_open_pending == 0);
1055
	  g_open_pending++;
1056
	  TC_MUTEX_UNLOCK(mutex_open);
1057
	  SAY("about to call trans_force_write(): (chan->sck = %d, chan->sck_out = %d, len = %d)", chan->sck, chan->sck_out, len);
1058
	  tres = trans_force_write(chan);
1059
	  if (tres < 0) {
1060
	    SAY("ERROR: trans_force_write() returned an error code (tres = %d)",tres);
1061
	    TC_MUTEX_LOCK(mutex_open);
1062
	    assert(g_open_pending == 1);
1063
	    g_open_pending--;
1064
	    TC_MUTEX_UNLOCK(mutex_open);
1065
	  }
1066
	  else {
1067
	    SAY("trans_force_write() returned (tres = %d)",tres);
1068
	  }
1069
	}
1070
	else {
1071
	  SAY("ERROR: unable to send (g_interface_type = %d)", g_interface_type);
1072
	}
1073
      }
1074
      if (pdu != NULL) {
1075
	g_free(pdu);
1076
	pdu = (MSG_SNDIN_OPEN *)NULL;
1077
      }
1078
    }
1079
1080
  end:;
1081
    if (locked) {
1082
      chan->locked = 0;
1083
      TC_MUTEX_UNLOCK(chan->lock);
1084
      locked = 0;
1085
    }
1086
    SAY("done.");
1087
    return rv;
1088
}
1089
1090
static int APP_CC handle_finish(struct trans * chan) {
1091
    int	rv = 0;
1092
1093
    if (chan != NULL) {
1094
      unsigned char locked = 0;
1095
      if (chan->lock != NULL) {
1096
	TC_MUTEX_LOCK(chan->lock);
1097
	chan->locked = 1;
1098
	locked = 1;
1099
      }
1100
      trans_detach(chan);
1101
      if (locked) {
1102
	chan->locked = 0;
1103
	TC_MUTEX_UNLOCK(chan->lock);
1104
	locked = 0;
1105
      }
1106
      g_free(chan);
1107
    }
1108
    g_sleep(200);
1109
    TC_MUTEX_LOCK(mutex_done);
1110
    g_done = 1;
1111
    TC_MUTEX_UNLOCK(mutex_done);
1112
    g_sleep(200);
1113
1114
  end:;
1115
    return rv;
1116
}
1117
1118
1119
static void * APP_CC pa_output_loop(void * arg) {
1120
    void * rv = (void *)NULL;
1121
    pa_simple * s = (pa_simple *)NULL;
1122
    unsigned char done = 0;
1123
    unsigned char plocked = 0;
1124
    uint8_t sbuf[(MAX_STREAM + 4)];
1125
    uint8_t * sdata = (uint8_t *)(&(sbuf[4]));
1126
    uint32_t * slen = (uint32_t *)sbuf;
1127
    ptrdiff_t ilen = 0;
1128
    stream_list_t litem;
1129
    stream_list_t * item = (stream_list_t *)NULL;
1130
1131
    SAY("called");
1132
1133
    TC_BARR_WAIT(barr_thread);
1134
1135
    return rv;
1136
1137
    pa_disable_sigpipe();
1138
    signal(SIGPIPE, SIG_IGN);
1139
1140
    while (!done) {
1141
	*slen = 0;
1142
	ilen = 0;
1143
	g_memset(&litem,0,sizeof(stream_list_t));
1144
	item = &litem;
1145
	if (!plocked) {
1146
	  TC_MUTEX_LOCK(mutex_pa);
1147
	  plocked = 1;
1148
	}
1149
	if (g_pa_count < 1) {
1150
	  g_pa_waiting++;
1151
	  TC_COND_WAIT(cond_pa, mutex_pa);
1152
	  //SAY("awakened: g_pa_count = %d",g_pa_count);
1153
	  g_pa_waiting--;
1154
	}
1155
	while (g_pa_count > 0) {
1156
	  int error = 0;
1157
	  item = (stream_list_t *)NULL;
1158
	  //item->s = g_pa_stream;
1159
	  SQ_DEQ(ilist, &item);
1160
	  if (item != NULL) {
1161
	    g_pa_count--;
1162
	  }
1163
	  if (item == NULL || item->s == NULL) {
1164
	    break;
1165
	  }
1166
	  ilen = (item->s->end > item->s->data) ? (item->s->end - item->s->data) : 0;
1167
	  if (ilen > 0) {
1168
	    *slen += ilen;
1169
	    g_memcpy(sdata, item->s->data, ilen);
1170
	    sdata += ilen;
1171
	  }
1172
	  //item = (stream_list_t *)NULL;
1173
	  if (item != NULL && item->s != NULL && item->s->data != NULL) {
1174
	    free_stream(item->s);
1175
	    item->s = (struct stream *)NULL;
1176
	  }
1177
	  if (item != NULL) {
1178
	    g_free(item);
1179
	    item = (stream_list_t *)NULL;
1180
	  }
1181
	}
1182
	if (*slen < 1) {
1183
	  if (plocked) {
1184
	    TC_MUTEX_UNLOCK(mutex_pa);
1185
	    plocked = 0;
1186
	  }
1187
	  continue;
1188
	}
1189
	else if (g_pa_trans != NULL && g_pa_trans->sck > -1) {
1190
		char * p = (char *)NULL;
1191
		unsigned char locked = 0;
1192
		struct stream * s = (struct stream *)NULL;
1193
		if (g_pa_trans->lock != NULL) {
1194
		  TC_MUTEX_LOCK(g_pa_trans->lock);
1195
		  g_pa_trans->locked = 1;
1196
		  locked = 1;
1197
		}
1198
		if (plocked) {
1199
		  TC_MUTEX_UNLOCK(mutex_pa);
1200
		  plocked = 0;
1201
		}
1202
		ilen = *slen + 4;
1203
		s = trans_get_out_s(g_pa_trans, MAX_STREAM);
1204
		p = s->p;
1205
		out_uint8a(s, sbuf, ilen);
1206
		s_mark_end(s);
1207
		SAY("about to send %d bytes to child (g_pfd = %d):",ilen,g_pfd);
1208
		{
1209
		  ptrdiff_t rem = ilen;
1210
		  int flags = g_pa_trans->send_flags;
1211
		  g_pa_trans->send_flags |= MSG_NOSIGNAL;
1212
		  if (1) {
1213
		    trans_force_write(g_pa_trans);
1214
		  }
1215
		  else while (rem > 0) {
1216
		    ptrdiff_t res = 0;
1217
		    res = write(g_pa_trans->sck, p, (s->end - p));
1218
		    if (res < 0) {
1219
			SAY("ERROR: res = %d",res);
1220
			break;
1221
		    }
1222
		    else {
1223
			rem -= res;
1224
		    }
1225
		  }
1226
		  g_pa_trans->send_flags = flags;
1227
		}
1228
		SAY("sent bytes to child.");
1229
		if (locked > 0) {
1230
		  g_pa_trans->locked = 0;
1231
		  TC_MUTEX_UNLOCK(g_pa_trans->lock);
1232
		  locked = 0;
1233
		}
1234
	}
1235
	else if (plocked) {
1236
		TC_MUTEX_UNLOCK(mutex_pa);
1237
		plocked = 0;
1238
	}
1239
	TC_MUTEX_LOCK(mutex_done);
1240
	done = g_done;
1241
	TC_MUTEX_UNLOCK(mutex_done);
1242
    }
1243
1244
  end:;
1245
    SAY("done.");
1246
    TC_THREAD_EXIT(NULL);
1247
    return rv;
1248
}
1249
1250
static int APP_CC sound_get_pulseaudio_server(const char ** server) {
1251
    int rv = 0;
1252
    glob_t tglob;
1253
    char globdir[164];
1254
    g_memset(globdir, 0, sizeof(globdir));
1255
    if (server == NULL) {
1256
      rv = -1;
1257
      goto end;
1258
    }
1259
    else {
1260
      *server = g_getenv("PULSE_SERVER");
1261
    }
1262
    if (*server == NULL) {
1263
      uid_t tuid = 0;
1264
      unsigned int idx = 0;
1265
      g_memset(&tglob,0,sizeof(glob_t));
1266
      pa_get_home_dir(globdir, sizeof(globdir) - 48);
1267
      g_strncat(globdir, "/.pulse/*-runtime/native", sizeof(globdir));
1268
      glob(globdir,GLOB_NOSORT,NULL,&tglob);
1269
      for (idx = 0; idx < tglob.gl_pathc; idx++) {
1270
	int fd = -1;
1271
	struct stat finfo;
1272
	g_memset(&finfo,0,sizeof(struct stat));
1273
	if (g_strlen(tglob.gl_pathv[idx]) > 0 && stat(tglob.gl_pathv[idx], &finfo) == 0) {
1274
	  if (S_ISSOCK(finfo.st_mode)) {
1275
	      *server = g_strndup(tglob.gl_pathv[idx], 164);
1276
	      break;
1277
	  }
1278
	}
1279
	else {
1280
	  continue;
1281
	}
1282
      }
1283
      globfree(&tglob);
1284
    }
1285
1286
  end:;
1287
    SAY("DEBUG: *server = \"%s\"",*server);
1288
    return rv;
1289
}
1290
1291
static tbus APP_CC launch_child() {
1292
    tbus rv = 0;
1293
    tbus fds[2] = { -1, -1 };
1294
    int cpid = 0;
1295
    int ppid = 0;
1296
    int tpid = 0;
1297
    tbus pfd = -1;
1298
    tbus cfd = -1;
1299
    unsigned char done = 0;
1300
    unsigned char locked = 0;
1301
1302
    g_socketpair((int *)fds);
1303
    cfd = fds[0];
1304
    pfd = fds[1];
1305
1306
    ppid = g_getpid();
1307
1308
    tpid = g_fork();
1309
    if (tpid < 0) {
1310
      SAY("ERROR: g_fork() failed");
1311
    }
1312
    else if (tpid == 0) {	/* child */
1313
      tbus fd_log = -1;
1314
      g_is_child = 1;
1315
      rv = -1;
1316
      cpid = g_getpid();
1317
      //g_tcp_close(pfd);
1318
      pfd = -1;
1319
      g_pfd = -1;
1320
1321
      launch_pa(&g_pa);
1322
1323
      g_pa_trans = trans_create(WO_LOCAL, MAX_STREAM, MAX_STREAM);
1324
      if (g_pa_trans == NULL) {
1325
	SAY("ERROR: g_pa_trans is NULL");
1326
	goto end;
1327
      }
1328
      trans_attach(g_pa_trans, cfd);
1329
      g_pa_trans->sck = cfd;
1330
      g_tcp_set_non_blocking(g_pa_trans->sck);
1331
      if (g_pa_trans != NULL) {
1332
	g_pa_trans->trans_data_in = pa_data_in;
1333
	g_pa_trans->callback_data = g_pa;
1334
	g_pa_trans->header_size = 0;
1335
	g_pa_trans->ready = 1;
1336
	g_pa_trans->running = 1;
1337
      }
1338
1339
      SAY("g_pa_trans = %p, g_pa_trans->sck = %d",g_pa_trans,g_pa_trans->sck);
1340
1341
      pa_disable_sigpipe();
1342
      signal(SIGPIPE, SIG_IGN);
1343
1344
      while (!done) {
1345
	tbus objs[8] = {0,0,0,0,0,0,0,0};
1346
	int count = 0;
1347
	int timeout = -1;
1348
	if (g_pa_trans == NULL) {
1349
	  SAY("g_pa_trans is NULL");
1350
	  continue;
1351
	}
1352
	else if (g_pa_trans->trans_data_in == NULL) {
1353
	  SAY("g_pa_trans->trans_data_in is NULL");
1354
	  continue;
1355
	}
1356
	if (trans_get_wait_objs(g_pa_trans, objs, &count, &timeout) != 0) {
1357
	  SAY("ERROR: trans_get_wait_objs() failed [status = %d]",g_pa_trans->status);
1358
	  done = 1;
1359
	  continue;
1360
	}
1361
	if (count > 0) {
1362
	  ptrdiff_t i = 0;
1363
	  unsigned char is_set = 0;
1364
	  g_obj_wait(objs, count, NULL, 0, timeout);
1365
	  for (i = 0; i < count; i++) if (g_tcp_socket_ok(objs[i]) && g_is_wait_obj_set(objs[i])) {
1366
	    is_set = 1;
1367
	    break;
1368
	  }
1369
	  if (is_set) {
1370
	    if (trans_check_wait_objs(g_pa_trans) < 0) {
1371
	      SAY("ERROR: trans_check_wait_objs() failed");
1372
	      done = 1;
1373
	    }
1374
	  }
1375
	}
1376
      }
1377
1378
    }
1379
    else {			/* parent */
1380
      unsigned char locked = 0;
1381
      pa_disable_sigpipe();
1382
      signal(SIGPIPE, SIG_IGN);
1383
      g_is_child = 0;
1384
      rv = pfd;
1385
      //g_tcp_close(cfd);
1386
      g_pa_trans = trans_create(WO_LOCAL, MAX_STREAM, MAX_STREAM);
1387
      if (g_pa_trans != NULL && g_pa_trans->lock != NULL) {
1388
	TC_MUTEX_LOCK(g_pa_trans->lock);
1389
	g_pa_trans->locked = 1;
1390
	locked = 1;
1391
      }
1392
      if (g_pa_trans != NULL) {
1393
	trans_attach(g_pa_trans, pfd);
1394
	g_pa_trans->sck = pfd;
1395
	g_tcp_set_non_blocking(g_pa_trans->sck);
1396
	g_pa_trans->trans_data_in = NULL;
1397
	g_pa_trans->callback_data = NULL;
1398
	g_pa_trans->header_size = 0;
1399
	g_pa_trans->ready = 1;
1400
	g_pa_trans->running = 1;
1401
      }
1402
      if (locked > 0) {
1403
	g_pa_trans->locked = 0;
1404
	TC_MUTEX_UNLOCK(g_pa_trans->lock);
1405
	locked = 0;
1406
      }
1407
    }
1408
1409
  end:;
1410
    return rv;
1411
}
1412
1413
static size_t APP_CC pa_data_in(struct trans * chan) {
1414
    size_t rv = 0;
1415
    if (chan == NULL) {
1416
      SAY("ERROR: chan is NULL");
1417
    }
1418
    else {
1419
      pa_simple * pa = (pa_simple *)(chan->callback_data);
1420
      struct stream * s = (struct stream *)NULL;
1421
      s = trans_get_in_s(chan);
1422
      trans_force_read(chan, 4);
1423
      if (s == NULL) {
1424
	SAY("ERROR: input stream is NULL");
1425
      }
1426
      else if (pa == NULL) {
1427
	SAY("ERROR: pa is NULL");
1428
      }
1429
      else {
1430
	int error = 0;
1431
	uint8_t * ptr = (uint8_t *)NULL;
1432
	size_t len = 0;
1433
	uint32_t tlen = 0;
1434
	in_uint32_le(s, tlen);
1435
	len = (size_t)(MIN(tlen,(MAX_STREAM - 4)));
1436
	ptr = (uint8_t *)(s->p);
1437
	trans_force_read(chan, len);
1438
	if (g_fd_log > -1 && len > 0) {
1439
	  g_file_write(g_fd_log, ptr, len);
1440
	}
1441
	if ((len > 0) && (pa_simple_write(pa, ptr, len, &error) < 0)) {
1442
	  SAY("ERROR: pa_simple_write() returned code %d [%s]",error,pa_strerror(error));
1443
	}
1444
	else {
1445
	  rv = len;
1446
	}
1447
      }
1448
    }
1449
  end:;
1450
    // SAY("done. (rv = %d)",rv);
1451
    return rv;
1452
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/dynamic/xrdp_rdpeai.h (+80 lines)
Line 0    Link Here 
1
#if !defined(XRDP_RDPEAI_H)
2
#define	XRDP_RDPEAI_H
3
4
#include <errno.h>
5
#include <netdb.h>
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <stdint.h>
9
#include <string.h>
10
#include <unistd.h>
11
#include <netinet/in.h>
12
#include <sys/types.h>
13
#include <sys/socket.h>
14
#include <pulse/pulseaudio.h>
15
16
#include "defines.h"
17
#include "arch.h"
18
#include "crc32.h"
19
#include "parse.h"
20
#include "os_calls.h"
21
#include "rdpdr.h"
22
#include "rdpdr_methods.h"
23
#include "stream_list.h"
24
#include "thread_calls.h"
25
#include "thread_macros.h"
26
#include "trans.h"
27
#include "drdynvc_defs.h"
28
#include "recording_defs.h"
29
30
#if !defined(SAY)
31
#define	SAY(...) {						\
32
	char cbuf[4096];					\
33
	g_memset(cbuf,0,sizeof(cbuf));				\
34
	g_snprintf(cbuf,sizeof(cbuf),__VA_ARGS__);		\
35
	if (0) { g_writeln("[%s() @ line %d]: %s", __func__, __LINE__, cbuf); }	\
36
	g_write_err("[%s() @ line %d]: %s\n", __func__, __LINE__, cbuf);	\
37
}
38
#endif
39
40
#if !defined(TC_COND_REINIT)
41
#define TC_COND_REINIT(x) {					\
42
	tc_t	tattr;						\
43
	tc_p	pattr = &tattr;					\
44
	g_memset(pattr,0,sizeof(tc_t));				\
45
	g_memset(x, 0, sizeof(tc_t));				\
46
	TC_CONDATTR_INIT(pattr);				\
47
	TC_CONDATTR_SETPSHARED(pattr, TC_PROCESS_SHARED);	\
48
	TC_COND_CREATE(x, pattr);				\
49
}
50
#endif
51
52
typedef enum rdpeai_interface {
53
	RDPEAI_INET = WO_INET,
54
#define	RDPEAI_INET RDPEAI_INET
55
	RDPEAI_SOCKET = WO_LOCAL,
56
#define	RDPEAI_SOCKET RDPEAI_SOCKET
57
	RDPEAI_FIFO = WO_FIFO
58
#define	RDPEAI_FIFO RDPEAI_FIFO
59
} rdpeai_interface_t;
60
61
/*	{ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 0x0002, .nSamplesPerSec = 0x0000ac44, .nAvgBytesPerSec = 0x0002b110, .nBlockAlign = 0x0004, .wBitsPerSample = 0x0010, .cbSize = 0, .__constructor = NULL, .__destructor = NULL, .data = { } },		*/
62
63
#define RDPEAI_FORMATS_ALL {	\
64
	{ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 0x0002, .nSamplesPerSec = 0x00005622, .nAvgBytesPerSec = 0x00015888, .nBlockAlign = 0x0004, .wBitsPerSample = 0x0010, .cbSize = 0, },		\
65
	{ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 0x0001, .nSamplesPerSec = 0x00002B11, .nAvgBytesPerSec = 0x0000AC44, .nBlockAlign = 0x0004, .wBitsPerSample = 0x0008, .cbSize = 0, },		\
66
	{ .wFormatTag = WAVE_FORMAT_MULAW, .nChannels = 0x0002, .nSamplesPerSec = 0x00005622, .nAvgBytesPerSec = 0x0000ac44, .nBlockAlign = 0x0002, .wBitsPerSample = 0x0008, .cbSize = 0, },		\
67
	{ .wFormatTag = WAVE_FORMAT_MULAW, .nChannels = 0x0001, .nSamplesPerSec = 0x00002B11, .nAvgBytesPerSec = 0x00005622, .nBlockAlign = 0x0002, .wBitsPerSample = 0x0004, .cbSize = 0, },		\
68
	{ .wFormatTag = WAVE_FORMAT_ALAW, .nChannels = 0x0002, .nSamplesPerSec = 0x00005622, .nAvgBytesPerSec = 0x0000ac44, .nBlockAlign = 0x0002, .wBitsPerSample = 0x0008, .cbSize = 0, },		\
69
	{ .wFormatTag = WAVE_FORMAT_ALAW, .nChannels = 0x0001, .nSamplesPerSec = 0x00002B11, .nAvgBytesPerSec = 0x00005622, .nBlockAlign = 0x0002, .wBitsPerSample = 0x0004, .cbSize = 0, },		\
70
}
71
72
#define RDPEAI_FORMATS_DEFAULT {	\
73
	{ .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 0x0002, .nSamplesPerSec = 0x00005622, .nAvgBytesPerSec = 0x00015888, .nBlockAlign = 0x0004, .wBitsPerSample = 0x0010, .cbSize = 0, },		\
74
	{ .wFormatTag = WAVE_FORMAT_MULAW, .nChannels = 0x0002, .nSamplesPerSec = 0x00005622, .nAvgBytesPerSec = 0x0000ac44, .nBlockAlign = 0x0002, .wBitsPerSample = 0x0008, .cbSize = 0, },		\
75
}
76
77
/* #define	RDPEAI_NUM_FORMATS	(sizeof(rdpeai_audio_formats) / sizeof(AUDIO_FORMAT_REC))	*/
78
#define		RDPEAI_NUM_FORMATS	2
79
80
#endif
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/libscp/libscp_init.c (+2 lines)
 Lines 42-47    Link Here 
42
42
43
  scp_lock_init();
43
  scp_lock_init();
44
44
45
  log_message(s_log, LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__);
46
45
  return 0;
47
  return 0;
46
}
48
}
47
49
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/libscp/libscp_session.c (-3 / +17 lines)
 Lines 27-36    Link Here 
27
27
28
#include "libscp_session.h"
28
#include "libscp_session.h"
29
29
30
#include <sys/un.h>
31
#include <netinet/in.h>
30
#include <sys/types.h>
32
#include <sys/types.h>
31
#include <sys/socket.h>
32
#include <arpa/inet.h>
33
#include <arpa/inet.h>
33
34
35
#include "dbg.h"
36
34
extern struct log_config* s_log;
37
extern struct log_config* s_log;
35
38
36
/*******************************************************************/
39
/*******************************************************************/
 Lines 39-44    Link Here 
39
{
42
{
40
  struct SCP_SESSION* s;
43
  struct SCP_SESSION* s;
41
44
45
  MDBGLOG("libscp","[scp_session_create()]");
46
42
  s = (struct SCP_SESSION*)g_malloc(sizeof(struct SCP_SESSION), 1);
47
  s = (struct SCP_SESSION*)g_malloc(sizeof(struct SCP_SESSION), 1);
43
  if (0 == s)
48
  if (0 == s)
44
  {
49
  {
 Lines 52-57    Link Here 
52
int
57
int
53
scp_session_set_type(struct SCP_SESSION* s, tui8 type)
58
scp_session_set_type(struct SCP_SESSION* s, tui8 type)
54
{
59
{
60
  MDBGLOG("libscp","[scp_session_set_type()]");
61
55
  switch (type)
62
  switch (type)
56
  {
63
  {
57
    case SCP_SESSION_TYPE_XVNC:
64
    case SCP_SESSION_TYPE_XVNC:
 Lines 66-76    Link Here 
66
      if (NULL == s->mng)
73
      if (NULL == s->mng)
67
      {
74
      {
68
        log_message(s_log, LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
75
        log_message(s_log, LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
76
	MDBGLOG("libscp"," ^^^ (scp_session_set_type) [session:%d] internal error, returning", __LINE__);
69
        return 1;
77
        return 1;
70
      }
78
      }
71
      break;
79
      break;
72
    default:
80
    default:
73
      log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
81
      log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
82
      MDBGLOG("libscp", " ^^^ (scp_session_set_type) [session:%d] unknown type", __LINE__);
74
      return 1;
83
      return 1;
75
  }
84
  }
76
  return 0;
85
  return 0;
 Lines 121-126    Link Here 
121
    case 15:
130
    case 15:
122
    case 16:
131
    case 16:
123
    case 24:
132
    case 24:
133
    case 32:
124
      s->bpp = bpp;
134
      s->bpp = bpp;
125
    default:
135
    default:
126
      return 1;
136
      return 1;
 Lines 165-170    Link Here 
165
  if (0 == str)
175
  if (0 == str)
166
  {
176
  {
167
    log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
177
    log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
178
    MDBGLOG("libscp","[scp_session_set_username()] (session:%d) null username",__LINE__);
168
    return 1;
179
    return 1;
169
  }
180
  }
170
  if (0 != s->username)
181
  if (0 != s->username)
 Lines 187-192    Link Here 
187
  if (0 == str)
198
  if (0 == str)
188
  {
199
  {
189
    log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
200
    log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
201
    MDBGLOG("libscp","[scp_session_set_password()] (session:%d) null password",__LINE__);
190
    return 1;
202
    return 1;
191
  }
203
  }
192
  if (0 != s->password)
204
  if (0 != s->password)
 Lines 335-343    Link Here 
335
    case SCP_ADDRESS_TYPE_IPV4:
347
    case SCP_ADDRESS_TYPE_IPV4:
336
      /* convert from char to 32bit*/
348
      /* convert from char to 32bit*/
337
      ret = inet_pton(AF_INET, addr, &ip4);
349
      ret = inet_pton(AF_INET, addr, &ip4);
338
      if (0 == ret)
350
      if (ret == 0)
339
      {
351
      {
340
        log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
352
        log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
353
	MDBGLOG("libscp","[session:%d] set_addr: invalid address\0", __LINE__);
341
        inet_pton(AF_INET, "127.0.0.1", &ip4);
354
        inet_pton(AF_INET, "127.0.0.1", &ip4);
342
        g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4);
355
        g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4);
343
        return 1;
356
        return 1;
 Lines 351-359    Link Here 
351
    case SCP_ADDRESS_TYPE_IPV6:
364
    case SCP_ADDRESS_TYPE_IPV6:
352
      /* convert from char to 128bit*/
365
      /* convert from char to 128bit*/
353
      ret = inet_pton(AF_INET6, addr, &ip6);
366
      ret = inet_pton(AF_INET6, addr, &ip6);
354
      if (0 == ret)
367
      if (ret == 0)
355
      {
368
      {
356
        log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
369
        log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
370
	MDBGLOG("libscp","[session:%d] set_addr: invalid address\0", __LINE__);
357
        inet_pton(AF_INET, "::1", &ip6);
371
        inet_pton(AF_INET, "::1", &ip6);
358
        g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16);
372
        g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16);
359
        return 1;
373
        return 1;
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/libscp/libscp_tcp.c (-9 / +110 lines)
 Lines 27-37    Link Here 
27
27
28
#include "libscp_tcp.h"
28
#include "libscp_tcp.h"
29
29
30
#include <sys/un.h>
31
#include <netdb.h>
30
#include <netinet/in.h>
32
#include <netinet/in.h>
31
#include <sys/socket.h>
32
#include <arpa/inet.h>
33
#include <arpa/inet.h>
33
#include <stdlib.h>
34
#include <stdlib.h>
34
#include <string.h>
35
#include <string.h>
36
#include <netdb.h>
37
38
#include "os_calls.h"
39
#include "dbg.h"
35
40
36
extern struct log_config* s_log;
41
extern struct log_config* s_log;
37
42
 Lines 120-134    Link Here 
120
}
125
}
121
126
122
/*****************************************************************************/
127
/*****************************************************************************/
123
int DEFAULT_CC
128
static int DEFAULT_CC
124
scp_tcp_bind(int sck, char* addr, char* port)
129
old_scp_tcp_bind(int sck, char* addr, char* port)
125
{
130
{
126
  struct sockaddr_in s;
131
//  struct sockaddr_storage sp;
132
//  struct sockaddr_in6 *s = NULL;
127
133
128
  memset(&s, 0, sizeof(struct sockaddr_in));
134
//  memset(s, 0, sizeof(struct sockaddr_storage));
129
  s.sin_family = AF_INET;
135
//  s.sin6_family = AF_INET6;
130
  s.sin_port = htons(atoi(port));
136
//  s.sin6_port = htons(atoi(port));
131
  s.sin_addr.s_addr = inet_addr(addr);
137
  //s.sin_addr.s_addr = inet_addr(addr);
132
  return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
138
//  return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
139
  return 0;
140
}
141
142
/*****************************************************************************/
143
int DEFAULT_CC
144
old2_scp_tcp_bind(int sck, char* addr, char* port) {
145
  int res = 0;
146
  struct in6_addr any6addr = IN6ADDR_ANY_INIT;
147
  struct sockaddr_storage sp;
148
  struct sockaddr_in6 * s = (struct sockaddr_in6 *)NULL;
149
  char tbuf[256];
150
151
  g_snprintf(tbuf,511,"[libscp]->scp_tcp_bind() called: sck = %d; addr = %s; port = %s\0",sck,addr,port);
152
  DBGLOG("net",tbuf);
153
154
  s = (struct sockaddr_in6 *)&sp;
155
  memset(s, 0, sizeof(struct sockaddr_storage));
156
  s->sin6_family = AF_INET6;
157
  s->sin6_port = htons((tui16)atoi(port));
158
  s->sin6_flowinfo = 0;
159
  //s->sin6_addr = in6addr_any;
160
  s->sin6_addr = any6addr;
161
  res = bind(sck, (struct sockaddr *)s, sizeof(*s));
162
  g_snprintf(tbuf,255," ** scp_tcp_bind(): res = %d\0",res);
163
  DBGLOG("net",tbuf);
164
  return res;
133
}
165
}
134
166
167
168
/*****************************************************************************/
169
int DEFAULT_CC
170
scp_tcp_bind_flags(int sck, char* addr, char* port, int flags) {
171
  int res = -1;
172
  int error = 0;
173
#ifdef _XRDP_ENABLE_IPv6_
174
  int ipv4count = 0;
175
#endif
176
  char * service = (char *)NULL;
177
  struct addrinfo hints;
178
  struct addrinfo * i = (struct addrinfo *)NULL;
179
  struct addrinfo * j = (struct addrinfo *)NULL;
180
181
  /* initialize (zero out) local variables: */
182
  g_memset(&hints, 0, sizeof(hints));
183
184
  hints.ai_family = AF_UNSPEC;
185
  hints.ai_flags = flags;
186
  hints.ai_socktype = SOCK_STREAM;
187
  hints.ai_protocol = IPPROTO_TCP;
188
  error = getaddrinfo(addr,port,&hints,&i);
189
  if (error) {
190
    MDBGLOG("libscp","[scp_tcp_bind()] ERROR: %d\0",error);
191
    res = -1;
192
  }
193
  else {
194
    /* iterate the entire list returned by getaddrinfo()
195
     * and determine how many IPv6 and IPv4 addresses, respectively,
196
     * are available:
197
     */
198
    j = i;
199
#ifdef _XRDP_ENABLE_IPv6_
200
    while ((j != NULL) && (res < 0)) {
201
      if (j->ai_family == PF_INET6) {
202
	res = bind(sck, (struct sockaddr *)j->ai_addr, j->ai_addrlen);
203
      }
204
      else {
205
	ipv4count++;
206
      }
207
      j = j->ai_next;
208
    }
209
    if ((res < 0) && (ipv4count > 0)) {
210
      j = i;
211
      while ((j != NULL) && (res < 0)) {
212
	res = bind(sck, (struct sockaddr *)j->ai_addr, j->ai_addrlen);
213
	j = j->ai_next;
214
      }
215
    }
216
#else
217
    while ((j != NULL) && (res < 0)) {
218
      res = bind(sck, (struct sockaddr *)j->ai_addr, j->ai_addrlen);
219
      j = j->ai_next;
220
    }
221
#endif
222
  }
223
224
  return res;  
225
}
226
227
228
/*****************************************************************************/
229
int DEFAULT_CC
230
scp_tcp_bind(int sck, char* addr, char* port) {
231
  int flags = 0;
232
  //flags = AI_PASSIVE | AI_ADDRCONFIG;
233
  flags = AI_ADDRCONFIG;
234
  return scp_tcp_bind_flags(sck, addr, port, flags);
235
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/libscp/libscp_tcp.h (+13 lines)
 Lines 60-65    Link Here 
60
 * @param sck Listening socket
60
 * @param sck Listening socket
61
 * @param addr Listening address
61
 * @param addr Listening address
62
 * @param port Listening port
62
 * @param port Listening port
63
 * @param flags getaddrinfo() hint flags
64
 * @return 0 on success, -1 on error
65
 *
66
 */
67
int DEFAULT_CC
68
scp_tcp_bind_flags(int sck, char* addr, char* port, int flags);
69
70
/**
71
 *
72
 * @brief Binds the listening socket
73
 * @param sck Listening socket
74
 * @param addr Listening address
75
 * @param port Listening port
63
 * @return 0 on success, -1 on error
76
 * @return 0 on success, -1 on error
64
 *
77
 *
65
 */
78
 */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/libscp/libscp_v1s.c (+6 lines)
 Lines 61-66    Link Here 
61
      return SCP_SERVER_STATE_NETWORK_ERR;
61
      return SCP_SERVER_STATE_NETWORK_ERR;
62
    }
62
    }
63
  }
63
  }
64
  else
65
  {
66
    version = 1;
67
  }
64
68
65
  in_uint32_be(c->in_s, size);
69
  in_uint32_be(c->in_s, size);
66
  if (size < 12)
70
  if (size < 12)
 Lines 238-243    Link Here 
238
242
239
  /* send password request */
243
  /* send password request */
240
  version=1;
244
  version=1;
245
  size=12;
246
  cmdset=0;
241
  cmd=3;
247
  cmd=3;
242
248
243
  out_uint32_be(c->out_s, version);                 /* version */
249
  out_uint32_be(c->out_s, version);                 /* version */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/libscp/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 25-28    Link Here 
25
  libscp_vX.c
33
  libscp_vX.c
26
34
27
libscp_la_LIBADD = \
35
libscp_la_LIBADD = \
28
  $(top_srcdir)/common/libcommon.la
36
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/lock.c (-4 / +4 lines)
 Lines 25-34    Link Here 
25
25
26
extern struct config_sesman* g_cfg; /* in sesman.c */
26
extern struct config_sesman* g_cfg; /* in sesman.c */
27
27
28
static tbus g_sync_mutex = 0;
28
static tc_p g_sync_mutex = 0;
29
static tbus g_lock_chain = 0;
29
static tc_p g_lock_chain = 0;
30
static tbus g_sync_sem = 0;
30
static tc_p g_sync_sem = 0;
31
static tbus g_lock_socket = 0;
31
static tc_p g_lock_socket = 0;
32
32
33
/******************************************************************************/
33
/******************************************************************************/
34
void APP_CC
34
void APP_CC
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/Makefile.am (-5 / +15 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED \
12
  -D_POSIX_PTHREAD_SEMANTICS \
13
  -D_POSIX_PTHREADS
14
15
LDFLAGS = \
16
  -lpthread
7
17
8
INCLUDES = \
18
INCLUDES = \
9
  -I$(top_srcdir)/common \
19
  -I$(top_srcdir)/common \
 Lines 46-53    Link Here 
46
  $(AUTH_C)
56
  $(AUTH_C)
47
57
48
xrdp_sesman_LDADD = \
58
xrdp_sesman_LDADD = \
49
  $(top_srcdir)/common/libcommon.la \
59
  $(top_builddir)/common/libcommon.la \
50
  $(top_srcdir)/sesman/libscp/libscp.la \
60
  $(top_builddir)/sesman/libscp/libscp.la \
51
  $(AUTH_LIB)
61
  $(AUTH_LIB)
52
62
53
sesmansysconfdir=$(sysconfdir)/xrdp
63
sesmansysconfdir=$(sysconfdir)/xrdp
 Lines 58-66    Link Here 
58
68
59
SUBDIRS = \
69
SUBDIRS = \
60
  libscp \
70
  libscp \
61
  tools \
62
  sessvc \
71
  sessvc \
63
  chansrv
72
  chansrv \
73
  dynamic
64
74
65
# must be tab below
75
# must be tab below
66
install-data-hook:
76
install-data-hook:
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/scp_v0.c (+1 lines)
 Lines 77-82    Link Here 
77
    if (display == 0)
77
    if (display == 0)
78
    {
78
    {
79
      auth_end(data);
79
      auth_end(data);
80
      data = 0;
80
      scp_v0s_deny_connection(c);
81
      scp_v0s_deny_connection(c);
81
    }
82
    }
82
    else
83
    else
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/scp_v1.c (+5 lines)
 Lines 29-34    Link Here 
29
29
30
//#include "libscp_types.h"
30
//#include "libscp_types.h"
31
#include "libscp.h"
31
#include "libscp.h"
32
#include "dbg.h"
32
33
33
extern struct config_sesman* g_cfg; /* in sesman.c */
34
extern struct config_sesman* g_cfg; /* in sesman.c */
34
35
 Lines 48-53    Link Here 
48
  int scount;
49
  int scount;
49
  SCP_SID sid;
50
  SCP_SID sid;
50
51
52
  MDBGLOG("sesman","scp_v1_process() called");
53
51
  retries = g_cfg->sec.login_retry;
54
  retries = g_cfg->sec.login_retry;
52
  current_try = retries;
55
  current_try = retries;
53
56
 Lines 186-191    Link Here 
186
189
187
static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f)
190
static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f)
188
{
191
{
192
  MDBGLOG("sesman","parseCommonStates() called");
193
189
  switch (e)
194
  switch (e)
190
  {
195
  {
191
    case SCP_SERVER_STATE_VERSION_ERR:
196
    case SCP_SERVER_STATE_VERSION_ERR:
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/scp_v1_mng.c (+5 lines)
 Lines 38-48    Link Here 
38
scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
38
scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
39
{
39
{
40
  long data;
40
  long data;
41
  int retries;
42
  int current_try;
41
  enum SCP_SERVER_STATES_E e;
43
  enum SCP_SERVER_STATES_E e;
42
  struct SCP_DISCONNECTED_SESSION* slist = 0;
44
  struct SCP_DISCONNECTED_SESSION* slist = 0;
43
  int scount;
45
  int scount;
44
  int end = 0;
46
  int end = 0;
45
47
48
  retries = g_cfg->sec.login_retry;
49
  current_try = retries;
50
46
  data = auth_userpass(s->username, s->password);
51
  data = auth_userpass(s->username, s->password);
47
  /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/
52
  /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/
48
53
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/sesman.c (-17 / +34 lines)
 Lines 25-31    Link Here 
25
 *
25
 *
26
 */
26
 */
27
27
28
#include <netdb.h>
28
#include "sesman.h"
29
#include "sesman.h"
30
#include "dbg.h"
29
31
30
int g_sck;
32
int g_sck;
31
int g_pid;
33
int g_pid;
 Lines 52-63    Link Here 
52
  int cont;
54
  int cont;
53
  tbus sck_obj;
55
  tbus sck_obj;
54
  tbus robjs[8];
56
  tbus robjs[8];
57
  char tbuf[512];
55
58
56
  /*main program loop*/
59
  /*main program loop*/
57
  log_message(&(g_cfg->log), LOG_LEVEL_INFO, "listening...");
60
  log_message(&(g_cfg->log), LOG_LEVEL_INFO, "listening...");
61
  g_snprintf(tbuf,511,"[%s()]: listening... (address = %s; port = %s)",__func__,g_cfg->listen_address, g_cfg->listen_port);
62
  //snprintf(tbuf,511," ^^^ listen_address = %s; listen_port = %s\0",g_cfg->listen_address,g_cfg->listen_port);
63
  DBGLOG("sesman",tbuf);
58
  g_sck = g_tcp_socket();
64
  g_sck = g_tcp_socket();
59
  g_tcp_set_non_blocking(g_sck);
65
  g_tcp_set_non_blocking(g_sck);
60
  error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);
66
  error = scp_tcp_bind_flags(g_sck, g_cfg->listen_address, g_cfg->listen_port, AI_ADDRCONFIG | AI_PASSIVE);
61
  if (error == 0)
67
  if (error == 0)
62
  {
68
  {
63
    error = g_tcp_listen(g_sck);
69
    error = g_tcp_listen(g_sck);
 Lines 87-109    Link Here 
87
          g_reset_wait_obj(g_sync_event);
93
          g_reset_wait_obj(g_sync_event);
88
          session_sync_start();
94
          session_sync_start();
89
        }
95
        }
90
        if (g_is_wait_obj_set(sck_obj)) /* incomming connection */
96
	if (g_is_wait_obj_set(sck_obj)) /* incoming connection */
91
        {
97
	{
92
          in_sck = g_tcp_accept(g_sck);
98
	  MDBGLOG("sesman","sesman_main_loop(): incoming connection!");
93
          if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck))
99
	  in_sck = g_tcp_accept(g_sck);
94
          {
100
	  if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck))
95
            /* should not get here */
101
	  {
96
            g_sleep(100);
102
	    /* should not get here */
97
          }
103
	    g_sleep(100);
98
          else if (in_sck == -1)
104
	  }
99
          {
105
	  else if (in_sck == -1)
100
            /* error, should not get here */
106
	  {
101
            break;
107
	    /* error, should not get here */
102
          }
108
	    break;
109
	  }
103
          else
110
          else
104
          {
111
          {
105
            /* we've got a connection, so we pass it to scp code */
112
            /* we've got a connection, so we pass it to scp code */
106
            LOG_DBG(&(g_cfg->log), "new connection");
113
            LOG_DBG(&(g_cfg->log), "new connection");
114
	    DBGLOG("sesman","[xdrp-sesman]->sesman_main_loop(): new connection");
107
            thread_scp_start(in_sck);
115
            thread_scp_start(in_sck);
108
            /* todo, do we have to wait here ? */
116
            /* todo, do we have to wait here ? */
109
          }
117
          }
 Lines 115-129    Link Here 
115
    {
123
    {
116
      log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "listen error %d (%s)",
124
      log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "listen error %d (%s)",
117
                  g_get_errno(), g_get_strerror());
125
                  g_get_errno(), g_get_strerror());
126
      snprintf(tbuf,511,"[xdrp-sesman]->sesman_main_loop(): listen error %d (%s)\0",g_get_errno(), g_get_strerror());
127
      DBGLOG("sesman",tbuf);
118
    }
128
    }
119
  }
129
  }
120
  else
130
  else {
121
  {
122
    log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "bind error on "
131
    log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "bind error on "
123
                "port '%s': %d (%s)", g_cfg->listen_port,
132
                "port '%s': %d (%s)", g_cfg->listen_port,
124
                g_get_errno(), g_get_strerror());
133
                g_get_errno(), g_get_strerror());
134
    snprintf(tbuf,511,"[xdrp-sesman]->sesman_main_loop(): bind error on port '%s': %d (%s)\0",g_cfg->listen_port,g_get_errno(), g_get_strerror());
135
    DBGLOG("sesman",tbuf);
125
  }
136
  }
126
  g_tcp_close(g_sck);
137
  g_tcp_close(g_sck);
138
  DBGLOG("sesman","[xdrp-sesman]->sesman_main_loop(): done.");
127
}
139
}
128
140
129
/******************************************************************************/
141
/******************************************************************************/
 Lines 137-148    Link Here 
137
  char pid_s[8];
149
  char pid_s[8];
138
  char text[256];
150
  char text[256];
139
  char pid_file[256];
151
  char pid_file[256];
152
  char tbuf[512];
140
153
141
  g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH);
154
  g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH);
142
  if (1 == argc)
155
  if (1 == argc)
143
  {
156
  {
144
    /* no options on command line. normal startup */
157
    /* no options on command line. normal startup */
145
    /* g_printf("starting sesman...\n"); */
158
    g_printf("starting sesman...\n");
146
    daemon = 1;
159
    daemon = 1;
147
  }
160
  }
148
  else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) ||
161
  else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) ||
 Lines 318-323    Link Here 
318
  /* start program main loop */
331
  /* start program main loop */
319
  log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
332
  log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
320
              "starting sesman with pid %d", g_pid);
333
              "starting sesman with pid %d", g_pid);
334
  snprintf(tbuf,511,"[xdrp-sesman]->main(): starting sesman with pid = %d\0",g_pid);
335
  DBGLOG("sesman",tbuf);
336
  
321
337
322
  /* make sure the /tmp/.X11-unix directory exist */
338
  /* make sure the /tmp/.X11-unix directory exist */
323
  if (!g_directory_exist("/tmp/.X11-unix"))
339
  if (!g_directory_exist("/tmp/.X11-unix"))
 Lines 347-352    Link Here 
347
    log_end(&(g_cfg->log));
363
    log_end(&(g_cfg->log));
348
  }
364
  }
349
365
366
  DBGLOG("sesman","[xdrp-sesman]->main(): done.");
350
  return 0;
367
  return 0;
351
}
368
}
352
369
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/sesman.ini (-2 / +6 lines)
 Lines 1-5    Link Here 
1
[Globals]
1
[Globals]
2
ListenAddress=127.0.0.1
2
ListenAddress=::
3
ListenPort=3350
3
ListenPort=3350
4
EnableUserWindowManager=1
4
EnableUserWindowManager=1
5
UserWindowManager=startwm.sh
5
UserWindowManager=startwm.sh
 Lines 20-26    Link Here 
20
[Logging]
20
[Logging]
21
LogFile=/var/log/xrdp-sesman.log
21
LogFile=/var/log/xrdp-sesman.log
22
LogLevel=DEBUG
22
LogLevel=DEBUG
23
EnableSyslog=0
23
EnableSyslog=1
24
SyslogLevel=DEBUG
24
SyslogLevel=DEBUG
25
25
26
[X11rdp]
26
[X11rdp]
 Lines 28-36    Link Here 
28
param2=-ac
28
param2=-ac
29
param3=-nolisten
29
param3=-nolisten
30
param4=tcp
30
param4=tcp
31
;param5=-depth
32
;param6=32
31
33
32
[Xvnc]
34
[Xvnc]
33
param1=-bs
35
param1=-bs
34
param2=-ac
36
param2=-ac
35
param3=-nolisten
37
param3=-nolisten
36
param4=tcp
38
param4=tcp
39
param5=-SecurityTypes
40
param6=None
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/session.c (-31 / +50 lines)
 Lines 27-32    Link Here 
27
27
28
#include "sesman.h"
28
#include "sesman.h"
29
#include "libscp_types.h"
29
#include "libscp_types.h"
30
#include "dbg.h"
30
31
31
#include <errno.h>
32
#include <errno.h>
32
//#include <time.h>
33
//#include <time.h>
 Lines 55-73    Link Here 
55
{
56
{
56
  struct session_chain* tmp;
57
  struct session_chain* tmp;
57
58
58
  /* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */
59
  switch (type)
60
  {
61
    case SCP_SESSION_TYPE_XVNC:
62
      type = SESMAN_SESSION_TYPE_XVNC;
63
      break;
64
    case SCP_SESSION_TYPE_XRDP:
65
      type = SESMAN_SESSION_TYPE_XRDP;
66
      break;
67
    default:
68
      return 0;
69
  }
70
71
  /*THREAD-FIX require chain lock */
59
  /*THREAD-FIX require chain lock */
72
  lock_chain_acquire();
60
  lock_chain_acquire();
73
61
 Lines 166-185    Link Here 
166
154
167
/******************************************************************************/
155
/******************************************************************************/
168
static void DEFAULT_CC
156
static void DEFAULT_CC
169
session_start_sessvc(int xpid, int wmpid, long data)
157
session_start_sessvc(int xpid, int wmpid, long data, char * uname, char * audio_fifo_path)
170
{
158
{
171
  struct list* sessvc_params;
159
  struct list * sessvc_params = (struct list *)NULL;
172
  char wmpid_str[25];
160
  char wmpid_str[25];
173
  char xpid_str[25];
161
  char xpid_str[25];
162
  char uname_str[100];
163
  char audio_str[256];
174
  char exe_path[262];
164
  char exe_path[262];
175
  int i;
165
  int i = 0;
166
167
  /* initialize (zero out) local variables: */
168
  g_memset(wmpid_str,0,sizeof(char) * 25);
169
  g_memset(xpid_str,0,sizeof(char) * 25);
170
  g_memset(exe_path,0,sizeof(char) * 262);
171
  g_memset(uname_str,0,sizeof(char) * 100);
172
  g_memset(audio_str,0,sizeof(char) * 256);
176
173
177
  /* new style waiting for clients */
174
  /* new style waiting for clients */
178
  g_sprintf(wmpid_str, "%d", wmpid);
175
  g_snprintf(wmpid_str, 24, "%d", wmpid);
179
  g_sprintf(xpid_str, "%d",  xpid);
176
  g_snprintf(xpid_str, 24, "%d",  xpid);
177
  g_snprintf(uname_str, 99, "%s",  uname);
178
  g_snprintf(audio_str, 255, "%s",  audio_fifo_path);
180
  log_message(&(g_cfg->log), LOG_LEVEL_INFO,
179
  log_message(&(g_cfg->log), LOG_LEVEL_INFO,
181
              "starting xrdp-sessvc - xpid=%s - wmpid=%s",
180
              "starting xrdp-sessvc - xpid=%s - wmpid=%s - uname=%s - audio_fifo_path=%s",
182
              xpid_str, wmpid_str);
181
              xpid_str, wmpid_str, uname_str, audio_str);
183
182
184
  sessvc_params = list_create();
183
  sessvc_params = list_create();
185
  sessvc_params->auto_free = 1;
184
  sessvc_params->auto_free = 1;
 Lines 190-195    Link Here 
190
  list_add_item(sessvc_params, (long)g_strdup(exe_path));
189
  list_add_item(sessvc_params, (long)g_strdup(exe_path));
191
  list_add_item(sessvc_params, (long)g_strdup(xpid_str));
190
  list_add_item(sessvc_params, (long)g_strdup(xpid_str));
192
  list_add_item(sessvc_params, (long)g_strdup(wmpid_str));
191
  list_add_item(sessvc_params, (long)g_strdup(wmpid_str));
192
  list_add_item(sessvc_params, (long)g_strdup(uname_str));
193
  list_add_item(sessvc_params, (long)g_strdup(audio_str));
193
  list_add_item(sessvc_params, 0); /* mandatory */
194
  list_add_item(sessvc_params, 0); /* mandatory */
194
195
195
  /* executing sessvc */
196
  /* executing sessvc */
 Lines 197-204    Link Here 
197
198
198
  /* should not get here */
199
  /* should not get here */
199
  log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
200
  log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
200
              "error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s",
201
              "error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s - uname=%s - audio_fifo_path=%s",
201
              g_getpid(), xpid_str, wmpid_str);
202
              g_getpid(), xpid_str, wmpid_str, uname_str, audio_str);
202
203
203
  /* logging parameters */
204
  /* logging parameters */
204
  /* no problem calling strerror for thread safety: other threads
205
  /* no problem calling strerror for thread safety: other threads
 Lines 300-321    Link Here 
300
                   char* password, tbus data, tui8 type, char* domain,
301
                   char* password, tbus data, tui8 type, char* domain,
301
                   char* program, char* directory)
302
                   char* program, char* directory)
302
{
303
{
303
  int display;
304
  int display = 0;
304
  int pid;
305
  int pid = 0;
305
  int wmpid;
306
  int wmpid = 0;
306
  int xpid;
307
  int xpid = 0;
307
  int i;
308
  int i = 0;
308
  char geometry[32];
309
  char geometry[32];
309
  char depth[32];
310
  char depth[32];
310
  char screen[32];
311
  char screen[32];
311
  char text[256];
312
  char text[256];
312
  char passwd_file[256];
313
  char passwd_file[256];
313
  char** pp1;
314
  char ** pp1 = (char **)NULL;
314
  struct session_chain* temp;
315
  char * audio_fifo_path = (char *)NULL;
315
  struct list* xserver_params=0;
316
  struct session_chain * temp = (struct session_chain *)NULL;
317
  struct list * xserver_params = (struct list *)NULL;
316
  time_t ltime;
318
  time_t ltime;
317
  struct tm stime;
319
  struct tm stime;
318
320
321
  /* initialize (zero out) local variables: */
322
  g_memset(&ltime,0,sizeof(time_t));
323
  g_memset(&stime,0,sizeof(struct tm));
324
  g_memset(geometry,0,sizeof(char) * 32);
325
  g_memset(depth,0,sizeof(char) * 32);
326
  g_memset(screen,0,sizeof(char) * 32);
327
  g_memset(text,0,sizeof(char) * 256);
328
  g_memset(passwd_file,0,sizeof(char) * 256);
329
319
  /* check to limit concurrent sessions */
330
  /* check to limit concurrent sessions */
320
  if (g_session_count >= g_cfg->sess.max_sessions)
331
  if (g_session_count >= g_cfg->sess.max_sessions)
321
  {
332
  {
 Lines 346-351    Link Here 
346
    g_free(temp);
357
    g_free(temp);
347
    return 0;
358
    return 0;
348
  }
359
  }
360
  wmpid = 0;
349
  pid = g_fork();
361
  pid = g_fork();
350
  if (pid == -1)
362
  if (pid == -1)
351
  {
363
  {
 Lines 527-533    Link Here 
527
        g_snprintf(text, 255, ":%d.0", display);
539
        g_snprintf(text, 255, ":%d.0", display);
528
        g_setenv("DISPLAY", text, 1);
540
        g_setenv("DISPLAY", text, 1);
529
        /* new style waiting for clients */
541
        /* new style waiting for clients */
530
        session_start_sessvc(xpid, wmpid, data);
542
	g_snprintf(text, 255, "%s", username);
543
	g_setenv("USER", text, 1);
544
	g_snprintf(text, 255, "/home/%s", username);
545
	g_setenv("HOME", text, 1);
546
	g_snprintf(text, 255, "/tmp/xrdp_audio_%d_fifo", wmpid);
547
	g_setenv("XRDP_AUDIO_FIFO", text, 1);
548
	audio_fifo_path = g_strdup(text);
549
        session_start_sessvc(xpid, wmpid, data, username, audio_fifo_path);
531
      }
550
      }
532
    }
551
    }
533
  }
552
  }
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/sessvc/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 15-18    Link Here 
15
  sessvc.c
23
  sessvc.c
16
24
17
xrdp_sessvc_LDADD = \
25
xrdp_sessvc_LDADD = \
18
  $(top_srcdir)/common/libcommon.la
26
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/sessvc/sessvc.c (-7 / +83 lines)
 Lines 25-36    Link Here 
25
 * 
25
 * 
26
 */
26
 */
27
27
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <errno.h>
31
#include <fcntl.h>
32
#include <unistd.h>
33
#include <pwd.h>
34
#include <sys/stat.h>
35
#include <sys/types.h>
28
#if defined(HAVE_CONFIG_H)
36
#if defined(HAVE_CONFIG_H)
29
#include "config_ac.h"
37
#include "config_ac.h"
30
#endif
38
#endif
31
#include "file_loc.h"
39
#include "file_loc.h"
32
#include "os_calls.h"
40
#include "os_calls.h"
33
#include "arch.h"
41
#include "arch.h"
42
#include "dbg.h"
43
44
34
45
35
static int g_term = 0;
46
static int g_term = 0;
36
47
 Lines 73-88    Link Here 
73
int DEFAULT_CC
84
int DEFAULT_CC
74
main(int argc, char** argv)
85
main(int argc, char** argv)
75
{
86
{
76
  int ret;
87
  int ret = 0;
77
  int chansrv_pid;
88
  int sessvc_pid = 0;
78
  int wm_pid;
89
  int chansrv_pid = 0;
79
  int x_pid;
90
  int wm_pid = 0;
80
  int lerror;
91
  int x_pid = 0;
92
  int lerror = 0;
93
  int fd_username = -1;
94
  int lckres = 0;
95
  int lexists = 0;
96
  char username[100];
97
  char audio_fifo_path[256];
98
  char fd_userfile[256];
81
  char exe_path[262];
99
  char exe_path[262];
100
  struct flock fl = { F_WRLCK, SEEK_SET, 0, 0, 0 };
101
102
  g_memset(username,0,sizeof(username));
103
  g_memset(audio_fifo_path,0,sizeof(audio_fifo_path));
104
  g_memset(fd_userfile,0,sizeof(fd_userfile));
105
  g_memset(exe_path,0,sizeof(exe_path));
106
107
  sessvc_pid = g_getpid();
82
108
83
  if (argc < 3)
109
  if (argc < 3)
84
  {
110
  {
85
    g_writeln("xrdp-sessvc: exiting, not enough params");
111
    g_writeln("xrdp-sessvc: exiting, not enough parameters");
86
    return 1;
112
    return 1;
87
  }
113
  }
88
  g_signal_kill(term_signal_handler); /* SIGKILL */
114
  g_signal_kill(term_signal_handler); /* SIGKILL */
 Lines 93-100    Link Here 
93
  wm_pid = g_atoi(argv[2]);
119
  wm_pid = g_atoi(argv[2]);
94
  g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)",
120
  g_writeln("xrdp-sessvc: waiting for X (pid %d) and WM (pid %d)",
95
             x_pid, wm_pid);
121
             x_pid, wm_pid);
122
123
  fl.l_type = F_WRLCK;
124
  fl.l_type = F_UNLCK;
125
  fl.l_whence = SEEK_SET;
126
  fl.l_start = 0;
127
  fl.l_len = 0;
128
  fl.l_pid = sessvc_pid;
129
96
  /* run xrdp-chansrv as a seperate process */
130
  /* run xrdp-chansrv as a seperate process */
131
97
  chansrv_pid = g_fork();
132
  chansrv_pid = g_fork();
133
134
  if ((chansrv_pid > 0) && (chansrv_pid != sessvc_pid)) {
135
    struct passwd * pw = (struct passwd *)NULL;
136
    uid_t tuid = 0;
137
    gid_t tgid = 0;
138
    if (argc > 3 && argv[3] != NULL) {
139
      g_snprintf(username,99,"%s",argv[3]);
140
    }
141
    else {
142
      g_snprintf(username,99,"%s",g_getenv("USER"));
143
    }
144
    pw = getpwnam((const char *)username);
145
    tuid = pw->pw_uid;
146
    tgid = pw->pw_gid;
147
    setgid(tgid);
148
    setuid(tuid);
149
    if (argc > 4 && argv[4] != NULL) {
150
      g_snprintf(audio_fifo_path,255,"%s",argv[4]);
151
    }
152
    else {
153
      g_snprintf(audio_fifo_path,255,"%s",g_getenv("XRDP_AUDIO_FIFO"));
154
    }
155
    g_snprintf(fd_userfile,255,CHANSRV_USERNAME_PATH,chansrv_pid);
156
    lexists = g_file_exist(fd_userfile);
157
    if (lexists < 1) {
158
      fd_username = g_file_open(fd_userfile);
159
    }
160
    if ((lexists < 1) && (fd_username > -1)) {
161
      lckres = g_file_lock(fd_username,0,0);			/* lock the file for writing */
162
      if (lckres > 0) {
163
        g_file_write(fd_username,username,g_strlen(username));
164
      }
165
      g_file_close(fd_username);
166
    }
167
  }
98
  if (chansrv_pid == -1)
168
  if (chansrv_pid == -1)
99
  {
169
  {
100
    g_writeln("xrdp-sessvc: fork error");
170
    g_writeln("xrdp-sessvc: fork error");
 Lines 106-112    Link Here 
106
    g_snprintf(exe_path, 261, "%s/xrdp-chansrv", XRDP_SBIN_PATH);
176
    g_snprintf(exe_path, 261, "%s/xrdp-chansrv", XRDP_SBIN_PATH);
107
    g_execlp3(exe_path, "xrdp-chansrv", 0);
177
    g_execlp3(exe_path, "xrdp-chansrv", 0);
108
    /* should not get here */
178
    /* should not get here */
109
    g_writeln("xrdp-sessvc: g_execvp failed");
179
    g_writeln("xrdp-sessvc: g_execlp3() failed");
110
    return 1;
180
    return 1;
111
  }
181
  }
112
  lerror = 0;
182
  lerror = 0;
 Lines 115-120    Link Here 
115
  while ((ret == 0) && !g_term)
185
  while ((ret == 0) && !g_term)
116
  {
186
  {
117
    ret = g_waitpid(wm_pid);
187
    ret = g_waitpid(wm_pid);
188
    g_sleep(1);
118
  }
189
  }
119
  if (ret < 0)
190
  if (ret < 0)
120
  {
191
  {
 Lines 129-134    Link Here 
129
  while ((ret == 0) && !g_term)
200
  while ((ret == 0) && !g_term)
130
  {
201
  {
131
    ret = g_waitpid(chansrv_pid);
202
    ret = g_waitpid(chansrv_pid);
203
    g_sleep(1);
132
  }
204
  }
133
  chansrv_cleanup(chansrv_pid);
205
  chansrv_cleanup(chansrv_pid);
134
  /* kill X server */
206
  /* kill X server */
 Lines 138-143    Link Here 
138
  while ((ret == 0) && !g_term)
210
  while ((ret == 0) && !g_term)
139
  {
211
  {
140
    ret = g_waitpid(x_pid);
212
    ret = g_waitpid(x_pid);
213
    g_sleep(1);
214
  }
215
  if (chansrv_pid > 0 && fd_userfile != NULL && g_strlen(fd_userfile) > 0) {
216
    unlink(fd_userfile);
141
  }
217
  }
142
  g_writeln("xrdp-sessvc: clean exit");
218
  g_writeln("xrdp-sessvc: clean exit");
143
  return 0;
219
  return 0;
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/startwm.sh (-8 / +50 lines)
 Lines 3-9    Link Here 
3
# change the order in line below to run to run whatever window manager you
3
# change the order in line below to run to run whatever window manager you
4
# want, default to kde
4
# want, default to kde
5
5
6
SESSIONS="startkde gnome-session startxfce4 xterm"
6
SESSIONS="startxfce4 gnome-session startkde wmaker fvwm2 xterm"
7
7
8
# change PATH to be what your environment needs usually what is in
8
# change PATH to be what your environment needs usually what is in
9
# /etc/environment
9
# /etc/environment
 Lines 23-37    Link Here 
23
23
24
#. /etc/profile
24
#. /etc/profile
25
25
26
for WindowManager in $SESSIONS
26
# return value: (default to error code 1)
27
RV=1
28
29
if [ -z "${AUDIO_FIFO_PATH}" -o ! \( -p "${AUDIO_FIFO_PATH}"  \) ]; then
30
  unset AUDIO_FIFO_PATH
31
fi
32
unset PA_MODNUM
33
34
PA_NATIVE=1
35
## PulseAudio:
36
if [ ${PA_NATIVE} -eq 0 ]; then
37
if [ -f /usr/bin/pactl ]; then
38
  if [ -f /usr/bin/mkfifo ]; then
39
    export AUDIO_FIFO_PATH="/tmp/xrdp_audio_${$}_fifo"
40
    if [ -z "${AUDIO_FIFO_PATH}" -o ! \( -p "${AUDIO_FIFO_PATH}"  \) ]; then
41
      if [ -p "${AUDIO_FIFO_PATH}" ]; then
42
        rm ${AUDIO_FIFO_PATH}
43
      fi
44
      /usr/bin/mkfifo ${AUDIO_FIFO_PATH}
45
      /bin/chmod 0666 ${AUDIO_FIFO_PATH}
46
    fi
47
    PA_MODNUM=$(/usr/bin/pactl load-module module-pipe-sink file=$AUDIO_FIFO_PATH sink_name=xrdp_$$)
48
    ## echo $PA_MODNUM > /tmp/a
49
50
/usr/bin/pacmd <<EOF
51
	set-default-sink xrdp_$$
52
EOF
53
54
  fi
55
fi
56
fi
57
58
for WindowManager in ${SESSIONS}
27
do
59
do
28
  which $WindowManager
60
  which ${WindowManager}
29
  if test $? -eq 0
61
  if test $? -eq 0 -a ${RV} -ne 0
30
  then
62
  then
31
    echo "Starting $WindowManager"
63
    echo "Starting ${WindowManager}"
32
    $WindowManager
64
    ${WindowManager}
33
    exit 0
65
    RV=0
34
  fi
66
  fi
35
done
67
done
36
68
37
exit 1
69
if [ -n "{$PA_MODNUM}" ]; then
70
  /usr/bin/pactl unload-module ${PA_MODNUM}
71
fi
72
73
if [ -n "${AUDIO_FIFO_PATH}" ]; then
74
  if [ -f "${AUDIO_FIFO_PATH}" ]; then
75
    rm ${AUDIO_FIFO_PATH}
76
  fi
77
fi
78
79
exit ${RV}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/tools/Makefile.am (-1 / +8 lines)
 Lines 3-9    Link Here 
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
7
  -D_FILE_OFFSET_BITS=64 \
8
  -D_REENTRANT \
9
  -D_GNU_SOURCE \
10
  -D_XOPEN_SOURCE_EXTENDED
7
11
8
INCLUDES = \
12
INCLUDES = \
9
  -I$(top_srcdir)/common \
13
  -I$(top_srcdir)/common \
 Lines 26-31    Link Here 
26
xrdp_sesadmin_SOURCES = \
30
xrdp_sesadmin_SOURCES = \
27
  sesadmin.c
31
  sesadmin.c
28
32
33
xrdp_tools_LDFLAGS = \
34
  -pthread
35
29
xrdp_sesrun_LDADD = \
36
xrdp_sesrun_LDADD = \
30
  $(top_srcdir)/common/libcommon.la
37
  $(top_srcdir)/common/libcommon.la
31
38
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/tools/sestest.c (-8 / +8 lines)
 Lines 55-64    Link Here 
55
  scp_session_set_width(s, 800);
55
  scp_session_set_width(s, 800);
56
  scp_session_set_bpp(s, 16);
56
  scp_session_set_bpp(s, 16);
57
  scp_session_set_rsr(s, 0);
57
  scp_session_set_rsr(s, 0);
58
  scp_session_set_locale(s, "it_IT");
58
  scp_session_set_locale(s, "en_US");
59
  scp_session_set_username(s, "prog");
59
  scp_session_set_username(s, "denise");
60
  scp_session_set_password(s, "prog");
60
  scp_session_set_password(s, "malonedm4");
61
  scp_session_set_hostname(s, "odin");
61
  scp_session_set_hostname(s, "lenny");
62
//   scp_session_set_addr(s, SCP_ADDRESS_TYPE_IPV4, "127.0.0.1");
62
//   scp_session_set_addr(s, SCP_ADDRESS_TYPE_IPV4, "127.0.0.1");
63
//   scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display);
63
//   scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display);
64
//   scp_session_set_errstr(struct SCP_SESSION* s, char* str);
64
//   scp_session_set_errstr(struct SCP_SESSION* s, char* str);
 Lines 69-83    Link Here 
69
  s.width=800;
69
  s.width=800;
70
  s.bpp=8;
70
  s.bpp=8;
71
  s.rsr=0;
71
  s.rsr=0;
72
  g_strncpy(s.locale,"it_IT  0123456789",18);
72
  g_strncpy(s.locale,"en_US  0123456789",18);
73
  s.username=g_malloc(256, 1);
73
  s.username=g_malloc(256, 1);
74
  g_strncpy(s.username,"prog",255);
74
  g_strncpy(s.username,"prog",255);
75
  s.password=g_malloc(256,1);
75
  s.password=g_malloc(256,1);
76
  g_strncpy(s.password, "prog", 255);
76
  g_strncpy(s.password, "prog", 255);
77
  g_printf("%s - %s\n", s.username, s.password);
77
  g_printf("%s - %s\n", s.username, s.password);
78
  s.hostname=g_malloc(256,1);
78
  s.hostname=g_malloc(256,1);
79
  g_strncpy(s.hostname, "odin", 255);
79
  g_strncpy(s.hostname, "lenny", 255);
80
  s.addr_type=SCP_ADDRESS_TYPE_IPV4;
80
  s.addr_type=SCP_ADDRESS_TYPE_IPV6;
81
  s.ipv4addr=0;
81
  s.ipv4addr=0;
82
  s.errstr=0;*/
82
  s.errstr=0;*/
83
83
 Lines 178-184    Link Here 
178
178
179
  /* fixed for now */
179
  /* fixed for now */
180
  s->rsr=0;
180
  s->rsr=0;
181
  g_strncpy(s->locale,"it_IT  0123456789",18);
181
  g_strncpy(s->locale,"en_US  0123456789",18);
182
182
183
  return 0;
183
  return 0;
184
}
184
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/tools/tcp.c (-7 / +99 lines)
 Lines 27-38    Link Here 
27
27
28
#include "sesman.h"
28
#include "sesman.h"
29
29
30
#include <sys/un.h>
31
#include <netdb.h>
30
#include <netinet/in.h>
32
#include <netinet/in.h>
31
#include <sys/socket.h>
33
#include <netinet/tcp.h>
32
#include <arpa/inet.h>
34
#include <arpa/inet.h>
33
#include <stdlib.h>
35
#include <stdlib.h>
34
#include <string.h>
36
#include <string.h>
35
37
38
#include "os_calls.h"
39
#include "dbg.h"
40
36
/*****************************************************************************/
41
/*****************************************************************************/
37
int DEFAULT_CC
42
int DEFAULT_CC
38
tcp_force_recv(int sck, char* data, int len)
43
tcp_force_recv(int sck, char* data, int len)
 Lines 133-145    Link Here 
133
138
134
/*****************************************************************************/
139
/*****************************************************************************/
135
int DEFAULT_CC
140
int DEFAULT_CC
141
old_tcp_bind(int sck, char* addr, char* port)
142
{
143
  int res = 0;
144
  struct in6_addr any6addr = IN6ADDR_ANY_INIT;
145
  struct sockaddr_storage sp;
146
  struct sockaddr_in6 * s = (struct sockaddr_in6 *)NULL;
147
  char tbuf[512];
148
149
  snprintf(tbuf,511,"[tools/tcp]->tcp_bind() called: sck = %d; addr = %s; port = %s\0",sck,addr,port);
150
  DBGLOG("net",tbuf);
151
  s = (struct sockaddr_in6 *)&sp;
152
  memset(s, 0, sizeof(struct sockaddr_storage));
153
  s->sin6_family = AF_INET6;
154
  s->sin6_port = htons((tui16)atoi(port));
155
  s->sin6_flowinfo = 0;
156
  //s->sin6_addr = in6addr_any;
157
  s->sin6_addr = any6addr;
158
  res = bind(sck, (struct sockaddr *)s, sizeof(*s));
159
  snprintf(tbuf,255," ** tcp_bind(): res = %d\0",res);
160
  DBGLOG("net",tbuf);
161
  return res;
162
}
163
164
165
/*****************************************************************************/
166
int DEFAULT_CC
167
tcp_bind_flags(int sck, char* addr, char* port, int flags)
168
{
169
  int res = -1;
170
  int error = 0;
171
#ifdef _XRDP_ENABLE_IPv6_
172
  int ipv4count = 0;
173
#endif
174
  char * service = (char *)NULL;
175
  struct addrinfo hints;
176
  struct addrinfo * i = (struct addrinfo *)NULL;
177
  struct addrinfo * j = (struct addrinfo *)NULL;
178
179
  /* initialize (zero out) local variables: */
180
  g_memset(&hints, 0, sizeof(hints));
181
182
  hints.ai_family = AF_UNSPEC;
183
  hints.ai_flags = flags;
184
  hints.ai_socktype = SOCK_STREAM;
185
  hints.ai_protocol = IPPROTO_TCP;
186
  error = getaddrinfo(addr,port,&hints,&i);
187
  if (error) {
188
    res = -1;
189
  }
190
  else {
191
    /* iterate the entire list returned by getaddrinfo()
192
     * and determine how many IPv6 and IPv4 addresses, respectively,
193
     * are available:
194
     */
195
    j = i;
196
#ifdef _XRDP_ENABLE_IPv6_
197
    while (j && (res < 0)) {
198
      if (j->ai_family == PF_INET6) {
199
	res = bind(sck, j->ai_addr, j->ai_addrlen);
200
      }
201
      else {
202
	ipv4count++;
203
      }
204
      j = j->ai_next;
205
    }
206
    if ((res < 0) && (ipv4count > 0)) {
207
      j = i;
208
      while (j && (res < 0)) {
209
	if (j->ai_family != PF_INET6) {
210
	  res = bind(sck, j->ai_addr, j->ai_addrlen);
211
	}
212
      }
213
      j = j->ai_next;
214
    }
215
#else
216
    while (j && (res < 0)) {
217
      res = bind(sck, j->ai_addr, j->ai_addrlen);
218
      j = j->ai_next;
219
    }
220
#endif
221
  }
222
223
  return res;  
224
}
225
226
227
/*****************************************************************************/
228
int DEFAULT_CC
136
tcp_bind(int sck, char* addr, char* port)
229
tcp_bind(int sck, char* addr, char* port)
137
{
230
{
138
  struct sockaddr_in s;
231
  int flags = 0;
232
233
  MDBGLOG("net","[tools/tcp]->tcp_bind() called: sck = %d; addr = %s; port = %s\0",sck,addr,port);
139
234
140
  memset(&s, 0, sizeof(struct sockaddr_in));
235
  flags = AI_ADDRCONFIG | AI_PASSIVE;
141
  s.sin_family = AF_INET;
236
  return tcp_bind_flags(sck, addr, port, flags);
142
  s.sin_port = htons(atoi(port));
143
  s.sin_addr.s_addr = inet_addr(addr);
144
  return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
145
}
237
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/sesman/tools/tcp.h (+13 lines)
 Lines 58-63    Link Here 
58
 * @param sck Listening socket
58
 * @param sck Listening socket
59
 * @param addr Listening address
59
 * @param addr Listening address
60
 * @param port Listening port
60
 * @param port Listening port
61
 * @param flags getaddrinfo() hint flags
62
 * @return 0 on success, -1 on error
63
 *
64
 */
65
int DEFAULT_CC
66
tcp_bind_flags(int sck, char* addr, char* port, int flags);
67
68
/**
69
 *
70
 * @brief Binds the listening socket
71
 * @param sck Listening socket
72
 * @param addr Listening address
73
 * @param port Listening port
61
 * @return 0 on success, -1 on error
74
 * @return 0 on success, -1 on error
62
 *
75
 *
63
 */
76
 */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/vnc/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 14-17    Link Here 
14
libvnc_la_SOURCES = vnc.c
22
libvnc_la_SOURCES = vnc.c
15
23
16
libvnc_la_LIBADD = \
24
libvnc_la_LIBADD = \
17
  $(top_srcdir)/common/libcommon.la
25
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/vnc/vnc.c (-26 / +15 lines)
 Lines 21-26    Link Here 
21
*/
21
*/
22
22
23
#include "vnc.h"
23
#include "vnc.h"
24
#include "dbg.h"
24
25
25
/******************************************************************************/
26
/******************************************************************************/
26
/* taken from vncauth.c */
27
/* taken from vncauth.c */
 Lines 29-34    Link Here 
29
{
30
{
30
  char key[12];
31
  char key[12];
31
32
33
  VLOG("rfbEncryptBytes() called: bytes = %s; passwd = %s\0",bytes,passwd);
32
  /* key is simply password padded with nulls */
34
  /* key is simply password padded with nulls */
33
  g_memset(key, 0, sizeof(key));
35
  g_memset(key, 0, sizeof(key));
34
  g_strncpy(key, passwd, 8);
36
  g_strncpy(key, passwd, 8);
 Lines 44-49    Link Here 
44
{
46
{
45
  int rcvd;
47
  int rcvd;
46
48
49
  VLOG("lib_recv() called: data = %s; len = %d\0",data,len);
50
47
  if (v->sck_closed)
51
  if (v->sck_closed)
48
  {
52
  {
49
    return 1;
53
    return 1;
 Lines 87-92    Link Here 
87
{
91
{
88
  int sent;
92
  int sent;
89
93
94
  VLOG("lib_send() called: data = %s; len = %d\0",data,len);
95
90
  if (v->sck_closed)
96
  if (v->sck_closed)
91
  {
97
  {
92
    return 1;
98
    return 1;
 Lines 135-140    Link Here 
135
  int format;
141
  int format;
136
  struct stream* out_s;
142
  struct stream* out_s;
137
143
144
  VLOG("lib_process_channel_data() called\0");
145
138
  if (chanid == v->clip_chanid)
146
  if (chanid == v->clip_chanid)
139
  {
147
  {
140
    in_uint16_le(s, type);
148
    in_uint16_le(s, type);
 Lines 226-232    Link Here 
226
  int chanid;
234
  int chanid;
227
  int flags;
235
  int flags;
228
  char* data;
236
  char* data;
229
  char text[256];
230
237
231
  error = 0;
238
  error = 0;
232
  make_stream(s);
239
  make_stream(s);
 Lines 255-283    Link Here 
255
    key = param2;
262
    key = param2;
256
    if (key > 0)
263
    if (key > 0)
257
    {
264
    {
258
      if (key == 65027) /* altgr */
259
      {
260
        if (v->shift_state)
261
        {
262
          /* fix for mstsc sending left control down with altgr */
263
          init_stream(s, 8192);
264
          out_uint8(s, 4);
265
          out_uint8(s, 0); /* down flag */
266
          out_uint8s(s, 2);
267
          out_uint32_be(s, 65507); /* left control */
268
          lib_send(v, s->data, 8);
269
        }
270
      }
271
      init_stream(s, 8192);
265
      init_stream(s, 8192);
272
      out_uint8(s, 4);
266
      out_uint8(s, 4);
273
      out_uint8(s, msg == 15); /* down flag */
267
      out_uint8(s, msg == 15); /* down flag */
274
      out_uint8s(s, 2);
268
      out_uint8s(s, 2);
275
      out_uint32_be(s, key);
269
      out_uint32_be(s, key);
276
      error = lib_send(v, s->data, 8);
270
      error = lib_send(v, s->data, 8);
277
      if (key == 65507) /* left control */
278
      {
279
        v->shift_state = msg == 15;
280
      }
281
    }
271
    }
282
  }
272
  }
283
  else if (msg >= 100 && msg <= 110) /* mouse events */
273
  else if (msg >= 100 && msg <= 110) /* mouse events */
 Lines 327-334    Link Here 
327
int DEFAULT_CC
317
int DEFAULT_CC
328
get_pixel_safe(char* data, int x, int y, int width, int height, int bpp)
318
get_pixel_safe(char* data, int x, int y, int width, int height, int bpp)
329
{
319
{
330
  int start;
320
  int start = 0;
331
  int shift;
321
  int shift = 0;
332
322
333
  if (x < 0)
323
  if (x < 0)
334
  {
324
  {
 Lines 391-398    Link Here 
391
set_pixel_safe(char* data, int x, int y, int width, int height, int bpp,
381
set_pixel_safe(char* data, int x, int y, int width, int height, int bpp,
392
               int pixel)
382
               int pixel)
393
{
383
{
394
  int start;
384
  int start = 0;
395
  int shift;
385
  int shift = 0;
396
386
397
  if (x < 0)
387
  if (x < 0)
398
  {
388
  {
 Lines 828-839    Link Here 
828
818
829
  v->server_msg(v, "started connecting", 0);
819
  v->server_msg(v, "started connecting", 0);
830
  check_sec_result = 1;
820
  check_sec_result = 1;
831
  /* only support 8 and 16 bpp connections from rdp client */
821
  /* only support 8, 16 or 24 bpp connections from rdp clients */
832
  if ((v->server_bpp != 8) && (v->server_bpp != 15) &&
822
  if ((v->server_bpp != 8) && (v->server_bpp != 15) &&
833
      (v->server_bpp != 16) && (v->server_bpp != 24))
823
      (v->server_bpp != 16) && (v->server_bpp != 24))
834
  {
824
  {
835
    v->server_msg(v, "error - only supporting 8, 15, 16 and 24 bpp rdp \
825
    v->server_msg(v, "error - only 8, 15, 16 and 24 bpp RDP connections are supported", 0);
836
connections", 0);
837
    return 1;
826
    return 1;
838
  }
827
  }
839
  if (g_strcmp(v->ip, "") == 0)
828
  if (g_strcmp(v->ip, "") == 0)
 Lines 1073-1079    Link Here 
1073
  {
1062
  {
1074
    if (v->server_bpp != v->mod_bpp)
1063
    if (v->server_bpp != v->mod_bpp)
1075
    {
1064
    {
1076
      v->server_msg(v, "error - server and client bpp don't match", 0);
1065
      v->server_msg(v, "error - server bpp and client bpp do not match", 0);
1077
      error = 1;
1066
      error = 1;
1078
    }
1067
    }
1079
  }
1068
  }
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/lang.c (-7 lines)
 Lines 234-246    Link Here 
234
      g_file_close(fd);
234
      g_file_close(fd);
235
    }
235
    }
236
  }
236
  }
237
  else if (keylayout != 0x409)
238
  {
239
    g_free(filename);
240
    g_writeln("keymap for 0x%4.4x was not found. Falling back to 0x0409 instead",
241
	      keylayout);
242
    return get_keymaps(0x409, keymap);
243
  }
244
  g_free(filename);
237
  g_free(filename);
245
  return 0;
238
  return 0;
246
}
239
}
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/Makefile.am (-3 / +11 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common \
17
  -I$(top_srcdir)/common \
 Lines 28-35    Link Here 
28
  xrdp_wm.c
36
  xrdp_wm.c
29
37
30
xrdp_LDADD = \
38
xrdp_LDADD = \
31
  $(top_srcdir)/common/libcommon.la \
39
  $(top_builddir)/common/libcommon.la \
32
  $(top_srcdir)/libxrdp/libxrdp.la
40
  $(top_builddir)/libxrdp/libxrdp.la
33
41
34
xrdpsysconfdir=$(sysconfdir)/xrdp
42
xrdpsysconfdir=$(sysconfdir)/xrdp
35
43
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/xrdp_bitmap.c (-41 / +47 lines)
 Lines 83-90    Link Here 
83
xrdp_bitmap_create(int width, int height, int bpp,
83
xrdp_bitmap_create(int width, int height, int bpp,
84
                   int type, struct xrdp_wm* wm)
84
                   int type, struct xrdp_wm* wm)
85
{
85
{
86
  struct xrdp_bitmap* self;
86
  struct xrdp_bitmap* self = (struct xrdp_bitmap *)NULL;
87
  int Bpp;
87
  int Bpp = 0;
88
88
89
  self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1);
89
  self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1);
90
  self->type = type;
90
  self->type = type;
 Lines 124-130    Link Here 
124
                             int bpp, char* data,
124
                             int bpp, char* data,
125
                             struct xrdp_wm* wm)
125
                             struct xrdp_wm* wm)
126
{
126
{
127
  struct xrdp_bitmap* self;
127
  struct xrdp_bitmap* self = (struct xrdp_bitmap *)NULL;
128
128
129
  self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1);
129
  self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1);
130
  self->type = WND_TYPE_BITMAP;
130
  self->type = WND_TYPE_BITMAP;
 Lines 141-148    Link Here 
141
void APP_CC
141
void APP_CC
142
xrdp_bitmap_delete(struct xrdp_bitmap* self)
142
xrdp_bitmap_delete(struct xrdp_bitmap* self)
143
{
143
{
144
  int i;
144
  int i = 0;
145
  struct xrdp_mod_data* mod_data;
145
  struct xrdp_mod_data* mod_data = (struct xrdp_mod_data *)NULL;
146
146
147
  if (self == 0)
147
  if (self == 0)
148
  {
148
  {
 Lines 227-234    Link Here 
227
struct xrdp_bitmap* APP_CC
227
struct xrdp_bitmap* APP_CC
228
xrdp_bitmap_get_child_by_id(struct xrdp_bitmap* self, int id)
228
xrdp_bitmap_get_child_by_id(struct xrdp_bitmap* self, int id)
229
{
229
{
230
  int i;
230
  int i = 0;
231
  struct xrdp_bitmap* b;
231
  struct xrdp_bitmap* b = (struct xrdp_bitmap *)NULL;
232
232
233
  for (i = 0; i < self->child_list->count; i++)
233
  for (i = 0; i < self->child_list->count; i++)
234
  {
234
  {
 Lines 247-253    Link Here 
247
int APP_CC
247
int APP_CC
248
xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused)
248
xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused)
249
{
249
{
250
  struct xrdp_painter* painter;
250
  struct xrdp_painter* painter = (struct xrdp_painter *)NULL;
251
251
252
  if (self == 0)
252
  if (self == 0)
253
  {
253
  {
 Lines 284-292    Link Here 
284
static int APP_CC
284
static int APP_CC
285
xrdp_bitmap_get_index(struct xrdp_bitmap* self, int* palette, int color)
285
xrdp_bitmap_get_index(struct xrdp_bitmap* self, int* palette, int color)
286
{
286
{
287
  int r;
287
  int r = 0;
288
  int g;
288
  int g = 0;
289
  int b;
289
  int b = 0;
290
290
291
  r = (color & 0xff0000) >> 16;
291
  r = (color & 0xff0000) >> 16;
292
  g = (color & 0x00ff00) >> 8;
292
  g = (color & 0x00ff00) >> 8;
 Lines 302-308    Link Here 
302
int APP_CC
302
int APP_CC
303
xrdp_bitmap_resize(struct xrdp_bitmap* self, int width, int height)
303
xrdp_bitmap_resize(struct xrdp_bitmap* self, int width, int height)
304
{
304
{
305
  int Bpp;
305
  int Bpp = 0;
306
306
307
  if ((width == self->width) && (height == self->height))
307
  if ((width == self->width) && (height == self->height))
308
  {
308
  {
 Lines 320-325    Link Here 
320
    case 8: Bpp = 1; break;
320
    case 8: Bpp = 1; break;
321
    case 15: Bpp = 2; break;
321
    case 15: Bpp = 2; break;
322
    case 16: Bpp = 2; break;
322
    case 16: Bpp = 2; break;
323
    /* case 24: Bpp = 3; break;	*/
323
  }
324
  }
324
  g_free(self->data);
325
  g_free(self->data);
325
  self->data = (char*)g_malloc(width * height * Bpp, 0);
326
  self->data = (char*)g_malloc(width * height * Bpp, 0);
 Lines 334-349    Link Here 
334
int APP_CC
335
int APP_CC
335
xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
336
xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
336
{
337
{
337
  int fd;
338
  int fd = 0;
338
  int i;
339
  int i = 0;
339
  int j;
340
  int j = 0;
340
  int k;
341
  int k = 0;
341
  int color;
342
  int color = 0;
342
  int size;
343
  int size = 0;
343
  int palette1[256];
344
  int palette1[256];
344
  char type1[4];
345
  char type1[4];
345
  struct xrdp_bmp_header header;
346
  struct xrdp_bmp_header header;
346
  struct stream* s;
347
  struct stream* s = (struct stream *)NULL;
348
349
  g_memset(palette1,0,sizeof(int) * 256);
350
  g_memset(type1,0,sizeof(char) * 4);
351
  g_memset(&header,0,sizeof(struct xrdp_bmp_header));
347
352
348
  if (!g_file_exist(filename))
353
  if (!g_file_exist(filename))
349
  {
354
  {
 Lines 351-357    Link Here 
351
              filename);
356
              filename);
352
    return 1;
357
    return 1;
353
  }
358
  }
354
  s = 0;
359
  s = (struct stream *)NULL;
355
  fd = g_file_open(filename);
360
  fd = g_file_open(filename);
356
  if (fd != -1)
361
  if (fd != -1)
357
  {
362
  {
 Lines 588-594    Link Here 
588
    {
593
    {
589
      return GETPIXEL16(self->data, x, y, self->width);
594
      return GETPIXEL16(self->data, x, y, self->width);
590
    }
595
    }
591
    else if (self->bpp == 24)
596
    else if (self->bpp == 24 || self->bpp == 32)
592
    {
597
    {
593
      return GETPIXEL32(self->data, x, y, self->width);
598
      return GETPIXEL32(self->data, x, y, self->width);
594
    }
599
    }
 Lines 618-624    Link Here 
618
    {
623
    {
619
      SETPIXEL16(self->data, x, y, self->width, pixel);
624
      SETPIXEL16(self->data, x, y, self->width, pixel);
620
    }
625
    }
621
    else if (self->bpp == 24)
626
    else if (self->bpp == 24 || self->bpp == 32)
622
    {
627
    {
623
      SETPIXEL32(self->data, x, y, self->width, pixel);
628
      SETPIXEL32(self->data, x, y, self->width, pixel);
624
    }
629
    }
 Lines 634-644    Link Here 
634
                     struct xrdp_bitmap* dest,
639
                     struct xrdp_bitmap* dest,
635
                     int x, int y, int cx, int cy)
640
                     int x, int y, int cx, int cy)
636
{
641
{
637
  int i;
642
  int i = 0;
638
  int j;
643
  int j = 0;
639
  int destx;
644
  int destx = 0;
640
  int desty;
645
  int desty = 0;
641
  int pixel;
646
  int pixel = 0;
642
647
643
  if (self == 0)
648
  if (self == 0)
644
  {
649
  {
 Lines 670-676    Link Here 
670
  {
675
  {
671
    return 1;
676
    return 1;
672
  }
677
  }
673
  if (self->bpp == 24)
678
  if (self->bpp == 24 || self->bpp == 32)
674
  {
679
  {
675
    for (i = 0; i < cy; i++)
680
    for (i = 0; i < cy; i++)
676
    {
681
    {
 Lines 718-735    Link Here 
718
                              struct xrdp_bitmap* dest,
723
                              struct xrdp_bitmap* dest,
719
                              int x, int y, int cx, int cy)
724
                              int x, int y, int cx, int cy)
720
{
725
{
721
  int i;
726
  int i = 0;
722
  int j;
727
  int j = 0;
723
  int destx;
728
  int destx = 0;
724
  int desty;
729
  int desty = 0;
725
  int pixel;
730
  int pixel = 0;
726
  int crc;
731
  int crc = 0;
727
  int incs;
732
  int incs = 0;
728
  int incd;
733
  int incd = 0;
729
  unsigned char* s8;
734
  unsigned char* s8 = (unsigned char *)NULL;
730
  unsigned char* d8;
735
  unsigned char* d8 = (unsigned char *)NULL;
731
  unsigned short* s16;
736
  unsigned short* s16 = (unsigned short *)NULL;
732
  unsigned short* d16;
737
  unsigned short* d16 = (unsigned short *)NULL;
733
738
734
  if (self == 0)
739
  if (self == 0)
735
  {
740
  {
 Lines 761-768    Link Here 
761
  {
766
  {
762
    return 1;
767
    return 1;
763
  }
768
  }
769
  crc = dest->crc;
764
  CRC_START(crc);
770
  CRC_START(crc);
765
  if (self->bpp == 24)
771
  if (self->bpp == 24 || self->bpp == 32)
766
  {
772
  {
767
    for (i = 0; i < cy; i++)
773
    for (i = 0; i < cy; i++)
768
    {
774
    {
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/xrdp.c (-11 / +14 lines)
 Lines 32-39    Link Here 
32
static SERVICE_STATUS_HANDLE g_ssh = 0;
32
static SERVICE_STATUS_HANDLE g_ssh = 0;
33
static SERVICE_STATUS g_service_status;
33
static SERVICE_STATUS g_service_status;
34
#endif
34
#endif
35
static long g_sync_mutex = 0;
35
static tc_p g_sync_mutex = 0;
36
static long g_sync1_mutex = 0;
36
static tc_p g_sync1_mutex = 0;
37
static tbus g_term_event = 0;
37
static tbus g_term_event = 0;
38
static tbus g_sync_event = 0;
38
static tbus g_sync_event = 0;
39
/* syncronize stuff */
39
/* syncronize stuff */
 Lines 533-542    Link Here 
533
    }
533
    }
534
    if (0 != pid)
534
    if (0 != pid)
535
    {
535
    {
536
      /* g_writeln("process %d started ok", pid); */
536
      g_writeln("process %d started ok", pid);
537
      /* exit, this is the main process */
537
      /* exit, this is the main process */
538
      g_exit(0);
538
      g_exit(0);
539
    }
539
    }
540
    g_sleep(1000);
541
    g_file_close(0);
542
    g_file_close(1);
543
    g_file_close(2);
544
    g_file_open("/dev/null");
545
    g_file_open("/dev/null");
546
    g_file_open("/dev/null");
547
    /* end of daemonizing code */
548
  }
549
  if (!no_daemon)
550
  {
540
    /* write the pid to file */
551
    /* write the pid to file */
541
    pid = g_getpid();
552
    pid = g_getpid();
542
    fd = g_file_open(pid_file); /* xrdp.pid */
553
    fd = g_file_open(pid_file); /* xrdp.pid */
 Lines 552-565    Link Here 
552
      g_file_write(fd, text, g_strlen(text));
563
      g_file_write(fd, text, g_strlen(text));
553
      g_file_close(fd);
564
      g_file_close(fd);
554
    }
565
    }
555
    g_sleep(1000);
556
    g_file_close(0);
557
    g_file_close(1);
558
    g_file_close(2);
559
    g_file_open("/dev/null");
560
    g_file_open("/dev/null");
561
    g_file_open("/dev/null");
562
    /* end of daemonizing code */
563
  }
566
  }
564
#endif
567
#endif
565
  g_threadid = tc_get_threadid();
568
  g_threadid = tc_get_threadid();
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/xrdp_cache.c (-9 / +9 lines)
 Lines 128-148    Link Here 
128
int APP_CC
128
int APP_CC
129
xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
129
xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
130
{
130
{
131
  int i;
131
  int i = 0;
132
  int j;
132
  int j = 0;
133
  int oldest;
133
  int oldest = 0;
134
  int cache_id;
134
  int cache_id = 0;
135
  int cache_idx;
135
  int cache_idx = 0;
136
  int bmp_size;
136
  int bmp_size = 0;
137
  int e;
137
  int e = 0;
138
  int Bpp;
138
  int Bpp = 0;
139
139
140
  e = bitmap->width % 4;
140
  e = bitmap->width % 4;
141
  if (e != 0)
141
  if (e != 0)
142
  {
142
  {
143
    e = 4 - e;
143
    e = 4 - e;
144
  }
144
  }
145
  Bpp = (bitmap->bpp + 7) / 8;
145
  Bpp = (bitmap->bpp == 32) ? 3 : (bitmap->bpp + 7) / 8;
146
  bmp_size = (bitmap->width + e) * bitmap->height * Bpp;
146
  bmp_size = (bitmap->width + e) * bitmap->height * Bpp;
147
  self->bitmap_stamp++;
147
  self->bitmap_stamp++;
148
  /* look for match */
148
  /* look for match */
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/xrdp.ini (-34 / +4 lines)
 Lines 7-52    Link Here 
7
channel_code=1
7
channel_code=1
8
8
9
[xrdp1]
9
[xrdp1]
10
name=sesman-Xvnc
10
name=sesman-X11rdp
11
lib=libvnc.so
11
lib=libxup.so
12
username=ask
12
username=ask
13
password=ask
13
password=ask
14
ip=127.0.0.1
14
ip=::1
15
port=-1
15
port=-1
16
16
17
[xrdp2]
17
[xrdp2]
18
name=console
18
name=sesman-Xvnc
19
lib=libvnc.so
20
ip=127.0.0.1
21
port=5900
22
username=na
23
password=ask
24
25
[xrdp3]
26
name=vnc-any
27
lib=libvnc.so
28
ip=ask
29
port=ask5900
30
username=na
31
password=ask
32
33
[xrdp4]
34
name=sesman-any
35
lib=libvnc.so
19
lib=libvnc.so
36
ip=ask
37
port=-1
38
username=ask
39
password=ask
40
41
[xrdp5]
42
name=rdp-any
43
lib=librdp.so
44
ip=ask
45
port=ask3389
46
47
[xrdp6]
48
name=sesman-X11rdp
49
lib=libxup.so
50
username=ask
20
username=ask
51
password=ask
21
password=ask
52
ip=127.0.0.1
22
ip=127.0.0.1
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/xrdp_listen.c (-3 / +7 lines)
 Lines 20-30    Link Here 
20
20
21
*/
21
*/
22
22
23
#include <netdb.h>
23
#include "xrdp.h"
24
#include "xrdp.h"
25
#include "dbg.h"
24
26
25
/* 'g_process' is protected by the semaphore 'g_process_sem'.  One thread sets
27
/* 'g_process' is protected by the semaphore 'g_process_sem'.  One thread sets
26
   g_process and waits for the other to process it */
28
   g_process and waits for the other to process it */
27
static tbus g_process_sem = 0;
29
static tc_p g_process_sem = 0;
28
static struct xrdp_process* g_process = 0;
30
static struct xrdp_process* g_process = 0;
29
31
30
/*****************************************************************************/
32
/*****************************************************************************/
 Lines 166-171    Link Here 
166
  int error;
168
  int error;
167
  int robjs_count;
169
  int robjs_count;
168
  int cont;
170
  int cont;
171
  int flags = 0;
169
  char port[8];
172
  char port[8];
170
  tbus robjs[8];
173
  tbus robjs[8];
171
  tbus term_obj;
174
  tbus term_obj;
 Lines 178-184    Link Here 
178
  xrdp_listen_get_port(port, sizeof(port));
181
  xrdp_listen_get_port(port, sizeof(port));
179
  self->sck = g_tcp_socket();
182
  self->sck = g_tcp_socket();
180
  g_tcp_set_non_blocking(self->sck);
183
  g_tcp_set_non_blocking(self->sck);
181
  error = g_tcp_bind(self->sck, port);
184
  flags = AI_ADDRCONFIG | AI_PASSIVE;
185
  error = g_tcp_bind_flags(self->sck, port, flags);
182
  if (error != 0)
186
  if (error != 0)
183
  {
187
  {
184
    g_writeln("bind error in xrdp_listen_main_loop");
188
    g_writeln("bind error in xrdp_listen_main_loop");
 Lines 217-223    Link Here 
217
        g_reset_wait_obj(sync_obj);
221
        g_reset_wait_obj(sync_obj);
218
        g_loop();
222
        g_loop();
219
      }
223
      }
220
      if (g_is_wait_obj_set(sck_obj)) /* incomming connection */
224
      if (g_is_wait_obj_set(sck_obj)) /* incoming connection */
221
      {
225
      {
222
        error = g_tcp_accept(self->sck);
226
        error = g_tcp_accept(self->sck);
223
        if ((error == -1) && g_tcp_last_error_would_block(self->sck))
227
        if ((error == -1) && g_tcp_last_error_would_block(self->sck))
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/xrdp_mm.c (-93 / +134 lines)
 Lines 21-26    Link Here 
21
*/
21
*/
22
22
23
#include "xrdp.h"
23
#include "xrdp.h"
24
#include "dbg.h"
24
25
25
/*****************************************************************************/
26
/*****************************************************************************/
26
struct xrdp_mm* APP_CC
27
struct xrdp_mm* APP_CC
 Lines 28-33    Link Here 
28
{
29
{
29
  struct xrdp_mm* self;
30
  struct xrdp_mm* self;
30
31
32
  //DBGLOG("xrdp","[xrdp_mm_create()]");
33
31
  self = (struct xrdp_mm*)g_malloc(sizeof(struct xrdp_mm), 1);
34
  self = (struct xrdp_mm*)g_malloc(sizeof(struct xrdp_mm), 1);
32
  self->wm = owner;
35
  self->wm = owner;
33
  self->login_names = list_create();
36
  self->login_names = list_create();
 Lines 42-47    Link Here 
42
static long DEFAULT_CC
45
static long DEFAULT_CC
43
xrdp_mm_sync_unload(long param1, long param2)
46
xrdp_mm_sync_unload(long param1, long param2)
44
{
47
{
48
  //DBGLOG("xrdp","[xrdp_mm_sync_unload()]");
49
45
  return g_free_library(param1);
50
  return g_free_library(param1);
46
}
51
}
47
52
 Lines 53-58    Link Here 
53
  long rv;
58
  long rv;
54
  char* libname;
59
  char* libname;
55
60
61
  //DBGLOG("xrdp","[xrdp_mm_sync_load()]");
62
56
  libname = (char*)param1;
63
  libname = (char*)param1;
57
  rv = g_load_library(libname);
64
  rv = g_load_library(libname);
58
  return rv;
65
  return rv;
 Lines 62-67    Link Here 
62
static void APP_CC
69
static void APP_CC
63
xrdp_mm_module_cleanup(struct xrdp_mm* self)
70
xrdp_mm_module_cleanup(struct xrdp_mm* self)
64
{
71
{
72
  //DBGLOG("xrdp","[xrdp_mm_module_cleanup()]");
73
65
  if (self->mod != 0)
74
  if (self->mod != 0)
66
  {
75
  {
67
    if (self->mod_exit != 0)
76
    if (self->mod_exit != 0)
 Lines 88-93    Link Here 
88
void APP_CC
97
void APP_CC
89
xrdp_mm_delete(struct xrdp_mm* self)
98
xrdp_mm_delete(struct xrdp_mm* self)
90
{
99
{
100
  //DBGLOG("xrdp","[xrdp_mm_delete()]");
101
91
  if (self == 0)
102
  if (self == 0)
92
  {
103
  {
93
    return;
104
    return;
 Lines 106-121    Link Here 
106
static int APP_CC
117
static int APP_CC
107
xrdp_mm_send_login(struct xrdp_mm* self)
118
xrdp_mm_send_login(struct xrdp_mm* self)
108
{
119
{
109
  struct stream* s;
120
  struct stream * s = (struct stream *)NULL;
110
  int rv;
121
  int rv = 0;
111
  int index;
122
  int index = 0;
112
  int count;
123
  int count = 0;
113
  char* username;
124
  char * username = (char *)NULL;
114
  char* password;
125
  char * password = (char *)NULL;
115
  char* name;
126
  char * name = (char *)NULL;
116
  char* value;
127
  char * value = (char *)NULL;
117
128
118
  xrdp_wm_log_msg(self->wm, "sending login info to sesman");
129
  xrdp_wm_log_msg(self->wm, "Sending login information to sesman");
119
  username = 0;
130
  username = 0;
120
  password = 0;
131
  password = 0;
121
  self->code = 0;
132
  self->code = 0;
 Lines 143-151    Link Here 
143
  }
154
  }
144
  if ((username == 0) || (password == 0))
155
  if ((username == 0) || (password == 0))
145
  {
156
  {
146
    xrdp_wm_log_msg(self->wm, "error finding username and password");
157
    xrdp_wm_log_msg(self->wm, "Error finding username and password");
147
    return 1;
158
    return 1;
148
  }
159
  }
160
149
  s = trans_get_out_s(self->sesman_trans, 8192);
161
  s = trans_get_out_s(self->sesman_trans, 8192);
150
  s_push_layer(s, channel_hdr, 8);
162
  s_push_layer(s, channel_hdr, 8);
151
  /* this code is either 0 for Xvnc or 10 for X11rdp */
163
  /* this code is either 0 for Xvnc or 10 for X11rdp */
 Lines 154-168    Link Here 
154
  out_uint16_be(s, index);
166
  out_uint16_be(s, index);
155
  out_uint8a(s, username, index);
167
  out_uint8a(s, username, index);
156
  index = g_strlen(password);
168
  index = g_strlen(password);
169
157
  out_uint16_be(s, index);
170
  out_uint16_be(s, index);
158
  out_uint8a(s, password, index);
171
  out_uint8a(s, password, index);
159
  out_uint16_be(s, self->wm->screen->width);
172
  out_uint16_be(s, self->wm->screen->width);
160
  out_uint16_be(s, self->wm->screen->height);
173
  out_uint16_be(s, self->wm->screen->height);
161
  out_uint16_be(s, self->wm->screen->bpp);
174
  out_uint16_be(s, self->wm->screen->bpp);
175
162
  /* send domain */
176
  /* send domain */
163
  index = g_strlen(self->wm->client_info->domain);
177
  index = g_strlen(self->wm->client_info->domain);
164
  out_uint16_be(s, index);
178
  out_uint16_be(s, index);
165
  out_uint8a(s, self->wm->client_info->domain, index);
179
  out_uint8a(s, self->wm->client_info->domain, index);
180
166
  /* send program / shell */
181
  /* send program / shell */
167
  index = g_strlen(self->wm->client_info->program);
182
  index = g_strlen(self->wm->client_info->program);
168
  out_uint16_be(s, index);
183
  out_uint16_be(s, index);
 Lines 171-186    Link Here 
171
  index = g_strlen(self->wm->client_info->directory);
186
  index = g_strlen(self->wm->client_info->directory);
172
  out_uint16_be(s, index);
187
  out_uint16_be(s, index);
173
  out_uint8a(s, self->wm->client_info->directory, index);
188
  out_uint8a(s, self->wm->client_info->directory, index);
189
174
  s_mark_end(s);
190
  s_mark_end(s);
175
  s_pop_layer(s, channel_hdr);
191
  s_pop_layer(s, channel_hdr);
176
  out_uint32_be(s, 0); /* version */
192
  out_uint32_be(s, 0); /* version */
177
  index = (int)(s->end - s->data);
193
  index = (int)(s->end - s->data);
178
  out_uint32_be(s, index); /* size */
194
  out_uint32_be(s, index); /* size */
195
179
  rv = trans_force_write(self->sesman_trans);
196
  rv = trans_force_write(self->sesman_trans);
180
  if (rv != 0)
197
181
  {
198
  if (rv != 0) {
182
    xrdp_wm_log_msg(self->wm, "xrdp_mm_send_login: xrdp_mm_send failed");
199
    xrdp_wm_log_msg(self->wm, "xrdp_mm_send_login: xrdp_mm_send_login failed");
183
  }
200
  }
201
184
  return rv;
202
  return rv;
185
}
203
}
186
204
 Lines 216-221    Link Here 
216
      rv = 0;
234
      rv = 0;
217
    }
235
    }
218
  }
236
  }
237
219
  return rv;
238
  return rv;
220
}
239
}
221
240
 Lines 237-242    Link Here 
237
    g_snprintf(text, 255, "no library name specified in xrdp.ini, please add "
256
    g_snprintf(text, 255, "no library name specified in xrdp.ini, please add "
238
               "lib=libxrdp-vnc.so or similar");
257
               "lib=libxrdp-vnc.so or similar");
239
    xrdp_wm_log_msg(self->wm, text);
258
    xrdp_wm_log_msg(self->wm, text);
259
240
    return 1;
260
    return 1;
241
  }
261
  }
242
  if (lib[0] == 0)
262
  if (lib[0] == 0)
 Lines 244-249    Link Here 
244
    g_snprintf(text, 255, "empty library name specified in xrdp.ini, please "
264
    g_snprintf(text, 255, "empty library name specified in xrdp.ini, please "
245
               "add lib=libxrdp-vnc.so or similar");
265
               "add lib=libxrdp-vnc.so or similar");
246
    xrdp_wm_log_msg(self->wm, text);
266
    xrdp_wm_log_msg(self->wm, text);
267
247
    return 1;
268
    return 1;
248
  }
269
  }
249
  if (self->mod_handle == 0)
270
  if (self->mod_handle == 0)
 Lines 280-286    Link Here 
280
        self->mod = self->mod_init();
301
        self->mod = self->mod_init();
281
        if (self->mod != 0)
302
        if (self->mod != 0)
282
        {
303
        {
283
          g_writeln("loaded modual '%s' ok, interface size %d, version %d", lib,
304
          g_writeln("loaded module '%s' ok, interface size %d, version %d", lib,
284
                    self->mod->size, self->mod->version);
305
                    self->mod->size, self->mod->version);
285
        }
306
        }
286
      }
307
      }
 Lines 334-346    Link Here 
334
xrdp_mm_setup_mod2(struct xrdp_mm* self)
355
xrdp_mm_setup_mod2(struct xrdp_mm* self)
335
{
356
{
336
  char text[256];
357
  char text[256];
337
  char* name;
358
  char* name = (char *)NULL;
338
  char* value;
359
  char* value = (char *)NULL;
339
  int i;
360
  int i = 0;
340
  int rv;
361
  int rv = 0;
341
  int key_flags;
362
  int key_flags = 0;
342
  int device_flags;
363
  int device_flags = 0;
343
364
365
  g_memset(text,0,sizeof(char) * 256);
344
  rv = 1;
366
  rv = 1;
345
  text[0] = 0;
367
  text[0] = 0;
346
  if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event))
368
  if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event))
 Lines 432-444    Link Here 
432
static int APP_CC
454
static int APP_CC
433
xrdp_mm_trans_send_channel_setup(struct xrdp_mm* self, struct trans* trans)
455
xrdp_mm_trans_send_channel_setup(struct xrdp_mm* self, struct trans* trans)
434
{
456
{
435
  int index;
457
  int index = 0;
436
  int chan_id;
458
  int chan_id = 0;
437
  int chan_flags;
459
  int chan_flags = 0;
438
  int size;
460
  int size = 0;
439
  struct stream* s;
461
  struct stream* s = (struct stream *)NULL;
440
  char chan_name[256];
462
  char chan_name[256];
441
463
464
  g_memset(chan_name,0,sizeof(char) * 256);
465
442
  s = trans_get_out_s(trans, 8192);
466
  s = trans_get_out_s(trans, 8192);
443
  if (s == 0)
467
  if (s == 0)
444
  {
468
  {
 Lines 477-483    Link Here 
477
xrdp_mm_trans_send_channel_data_response(struct xrdp_mm* self,
501
xrdp_mm_trans_send_channel_data_response(struct xrdp_mm* self,
478
                                         struct trans* trans)
502
                                         struct trans* trans)
479
{
503
{
480
  struct stream* s;
504
  struct stream* s = (struct stream *)NULL;
481
505
482
  s = trans_get_out_s(trans, 8192);
506
  s = trans_get_out_s(trans, 8192);
483
  if (s == 0)
507
  if (s == 0)
 Lines 507-518    Link Here 
507
static int APP_CC
531
static int APP_CC
508
xrdp_mm_trans_process_channel_data(struct xrdp_mm* self, struct trans* trans)
532
xrdp_mm_trans_process_channel_data(struct xrdp_mm* self, struct trans* trans)
509
{
533
{
510
  struct stream* s;
534
  struct stream* s = (struct stream *)NULL;
511
  int size;
535
  int size = 0;
512
  int total_size;
536
  int total_size = 0;
513
  int chan_id;
537
  int chan_id = 0;
514
  int chan_flags;
538
  int chan_flags = 0;
515
  int rv;
539
  int rv = 0;
516
540
517
  s = trans_get_in_s(trans);
541
  s = trans_get_in_s(trans);
518
  if (s == 0)
542
  if (s == 0)
 Lines 539-548    Link Here 
539
xrdp_mm_chan_process_msg(struct xrdp_mm* self, struct trans* trans,
563
xrdp_mm_chan_process_msg(struct xrdp_mm* self, struct trans* trans,
540
                         struct stream* s)
564
                         struct stream* s)
541
{
565
{
542
  int rv;
566
  int rv = 0;
543
  int id;
567
  int id = 0;
544
  int size;
568
  int size = 0;
545
  char* next_msg;
569
  char* next_msg = (char *)NULL;
546
570
547
  rv = 0;
571
  rv = 0;
548
  while (s_check_rem(s, 8))
572
  while (s_check_rem(s, 8))
 Lines 579-592    Link Here 
579
/*****************************************************************************/
603
/*****************************************************************************/
580
/* this is callback from trans obj
604
/* this is callback from trans obj
581
   returns error */
605
   returns error */
582
static int APP_CC
606
static size_t APP_CC
583
xrdp_mm_chan_data_in(struct trans* trans)
607
xrdp_mm_chan_data_in(struct trans* trans)
584
{
608
{
585
  struct xrdp_mm* self;
609
  struct xrdp_mm* self = (struct xrdp_mm *)NULL;
586
  struct stream* s;
610
  struct stream* s = (struct stream *)NULL;
587
  int id;
611
  int id = 0;
588
  int size;
612
  int size = 0;
589
  int error;
613
  int error = 0;
590
614
591
  if (trans == 0)
615
  if (trans == 0)
592
  {
616
  {
 Lines 613-619    Link Here 
613
static int APP_CC
637
static int APP_CC
614
xrdp_mm_chan_send_init(struct xrdp_mm* self)
638
xrdp_mm_chan_send_init(struct xrdp_mm* self)
615
{
639
{
616
  struct stream* s;
640
  struct stream* s = (struct stream *)NULL;
617
641
618
  s = trans_get_out_s(self->chan_trans, 8192);
642
  s = trans_get_out_s(self->chan_trans, 8192);
619
  if (s == 0)
643
  if (s == 0)
 Lines 632-645    Link Here 
632
static int APP_CC
656
static int APP_CC
633
xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
657
xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
634
{
658
{
635
  int ok;
659
  int ok = 0;
636
  int display;
660
  int display = 0;
637
  int rv;
661
  int rv = 0;
638
  int index;
662
  int index = 0;
639
  char text[256];
663
  char text[256];
640
  char ip[256];
664
  char ip[256];
641
  char port[256];
665
  char port[256];
642
666
667
  g_memset(text,0,sizeof(char) * 256);
668
  g_memset(ip,0,sizeof(char) * 256);
669
  g_memset(port,0,sizeof(char) * 256);
643
  rv = 0;
670
  rv = 0;
644
  in_uint16_be(s, ok);
671
  in_uint16_be(s, ok);
645
  in_uint16_be(s, display);
672
  in_uint16_be(s, display);
 Lines 657-663    Link Here 
657
        xrdp_wm_set_login_mode(self->wm, 10);
684
        xrdp_wm_set_login_mode(self->wm, 10);
658
        self->wm->dragging = 0;
685
        self->wm->dragging = 0;
659
        /* connect channel redir */
686
        /* connect channel redir */
660
        if (strcmp(ip, "127.0.0.1") == 0)
687
	if ((ip == NULL) || (g_strcasecmp(ip, "") == 0) || (g_strcasecmp(ip, "socket") == 0) || (g_strcasecmp(ip, "localhost") == 0) || (g_strchr(ip, '/') != NULL))
661
        {
688
        {
662
          /* unix socket */
689
          /* unix socket */
663
          self->chan_trans = trans_create(2, 8192, 8192);
690
          self->chan_trans = trans_create(2, 8192, 8192);
 Lines 672-681    Link Here 
672
        self->chan_trans->trans_data_in = xrdp_mm_chan_data_in;
699
        self->chan_trans->trans_data_in = xrdp_mm_chan_data_in;
673
        self->chan_trans->header_size = 8;
700
        self->chan_trans->header_size = 8;
674
        self->chan_trans->callback_data = self;
701
        self->chan_trans->callback_data = self;
675
        /* try to connect up to 4 times */
702
        /* try to connect up to 2 times */
676
        for (index = 0; index < 4; index++)
703
        for (index = 0; index < 2; index++)
677
        {
704
        {
678
          if (trans_connect(self->chan_trans, ip, port, 3000) == 0)
705
          if (trans_connect(self->chan_trans, ip, port, 2000) == 0)
679
          {
706
          {
680
            self->chan_trans_up = 1;
707
            self->chan_trans_up = 1;
681
            break;
708
            break;
 Lines 711-716    Link Here 
711
    xrdp_wm_set_login_mode(self->wm, 11);
738
    xrdp_wm_set_login_mode(self->wm, 11);
712
    xrdp_mm_module_cleanup(self);
739
    xrdp_mm_module_cleanup(self);
713
  }
740
  }
741
714
  return rv;
742
  return rv;
715
}
743
}
716
744
 Lines 718-731    Link Here 
718
static int
746
static int
719
xrdp_mm_get_sesman_port(char* port, int port_bytes)
747
xrdp_mm_get_sesman_port(char* port, int port_bytes)
720
{
748
{
721
  int fd;
749
  int fd = -1;
722
  int error;
750
  int error = 0;
723
  int index;
751
  int index = 0;
724
  char* val;
752
  char* val = 0;
725
  char cfg_file[256];
753
  char cfg_file[256];
726
  struct list* names;
754
  struct list* names = (struct list *)NULL;
727
  struct list* values;
755
  struct list* values = (struct list *)NULL;
728
756
757
  g_memset(cfg_file,0,sizeof(char) * 256);
729
  /* default to port 3350 */
758
  /* default to port 3350 */
730
  g_strncpy(port, "3350", port_bytes - 1);
759
  g_strncpy(port, "3350", port_bytes - 1);
731
  /* see if port is in xrdp.ini file */
760
  /* see if port is in xrdp.ini file */
 Lines 761-766    Link Here 
761
    list_delete(values);
790
    list_delete(values);
762
    g_file_close(fd);
791
    g_file_close(fd);
763
  }
792
  }
793
764
  return 0;
794
  return 0;
765
}
795
}
766
796
 Lines 771-783    Link Here 
771
xrdp_mm_process_channel_data(struct xrdp_mm* self, tbus param1, tbus param2,
801
xrdp_mm_process_channel_data(struct xrdp_mm* self, tbus param1, tbus param2,
772
                             tbus param3, tbus param4)
802
                             tbus param3, tbus param4)
773
{
803
{
774
  struct stream* s;
804
  struct stream* s = (struct stream *)NULL;
775
  int rv;
805
  int rv = 0;
776
  int length;
806
  int length = 0;
777
  int total_length;
807
  int total_length = 0;
778
  int flags;
808
  int flags = 0;
779
  int id;
809
  int id = 0;
780
  char* data;
810
  char * data = (char *)NULL;
781
811
782
  rv = 0;
812
  rv = 0;
783
  if ((self->chan_trans != 0) && self->chan_trans_up)
813
  if ((self->chan_trans != 0) && self->chan_trans_up)
 Lines 792-798    Link Here 
792
      total_length = param4;
822
      total_length = param4;
793
      if (total_length < length)
823
      if (total_length < length)
794
      {
824
      {
795
        g_writeln("warning in xrdp_mm_process_channel_data total_len < length");
825
        g_writeln("WARNING in xrdp_mm_process_channel_data(): total_len < length");
796
        total_length = length;
826
        total_length = length;
797
      }
827
      }
798
      out_uint32_le(s, 0); /* version */
828
      out_uint32_le(s, 0); /* version */
 Lines 808-826    Link Here 
808
      rv = trans_force_write(self->chan_trans);
838
      rv = trans_force_write(self->chan_trans);
809
    }
839
    }
810
  }
840
  }
841
811
  return rv;
842
  return rv;
812
}
843
}
813
844
814
/*****************************************************************************/
845
/*****************************************************************************/
815
static int APP_CC
846
static size_t APP_CC
816
xrdp_mm_sesman_data_in(struct trans* trans)
847
xrdp_mm_sesman_data_in(struct trans* trans)
817
{
848
{
818
  struct xrdp_mm* self;
849
  struct xrdp_mm* self = (struct xrdp_mm *)NULL;
819
  struct stream* s;
850
  struct stream* s = (struct stream *)NULL;
820
  int version;
851
  int version = 0;
821
  int size;
852
  int size = 0;
822
  int error;
853
  int error = 0;
823
  int code;
854
  int code = 0;
824
855
825
  if (trans == 0)
856
  if (trans == 0)
826
  {
857
  {
 Lines 848-853    Link Here 
848
        break;
879
        break;
849
    }
880
    }
850
  }
881
  }
882
851
  return error;
883
  return error;
852
}
884
}
853
885
 Lines 855-875    Link Here 
855
int APP_CC
887
int APP_CC
856
xrdp_mm_connect(struct xrdp_mm* self)
888
xrdp_mm_connect(struct xrdp_mm* self)
857
{
889
{
858
  struct list* names;
890
  struct list* names = (struct list *)NULL;
859
  struct list* values;
891
  struct list* values = (struct list *)NULL;
860
  int index;
892
  int index = 0;
861
  int count;
893
  int count = 0;
862
  int use_sesman;
894
  int use_sesman = 0;
863
  int error;
895
  int error = 0;
864
  int ok;
896
  int ok = 0;
865
  int rv;
897
  int rv = 0;
866
  char* name;
898
  char* name = (char *)NULL;
867
  char* value;
899
  char* value = (char *)NULL;
868
  char ip[256];
900
  char ip[256];
869
  char errstr[256];
901
  char errstr[256];
870
  char text[256];
902
  char text[256];
871
  char port[8];
903
  char port[8];
872
904
905
  g_memset(ip,0,sizeof(char) * 256);
906
  g_memset(errstr,0,sizeof(char) * 256);
907
  g_memset(text,0,sizeof(char) * 256);
908
  g_memset(port,0,sizeof(char) * 8);
873
  rv = 0;
909
  rv = 0;
874
  use_sesman = 0;
910
  use_sesman = 0;
875
  names = self->login_names;
911
  names = self->login_names;
 Lines 949-954    Link Here 
949
    }
985
    }
950
  }
986
  }
951
  self->sesman_controlled = use_sesman;
987
  self->sesman_controlled = use_sesman;
988
952
  return rv;
989
  return rv;
953
}
990
}
954
991
 Lines 958-964    Link Here 
958
                      tbus* read_objs, int* rcount,
995
                      tbus* read_objs, int* rcount,
959
                      tbus* write_objs, int* wcount, int* timeout)
996
                      tbus* write_objs, int* wcount, int* timeout)
960
{
997
{
961
  int rv;
998
  int rv = 0;
962
999
963
  if (self == 0)
1000
  if (self == 0)
964
  {
1001
  {
 Lines 981-986    Link Here 
981
                                        write_objs, wcount, timeout);
1018
                                        write_objs, wcount, timeout);
982
    }
1019
    }
983
  }
1020
  }
1021
984
  return rv;
1022
  return rv;
985
}
1023
}
986
1024
 Lines 988-994    Link Here 
988
int APP_CC
1026
int APP_CC
989
xrdp_mm_check_wait_objs(struct xrdp_mm* self)
1027
xrdp_mm_check_wait_objs(struct xrdp_mm* self)
990
{
1028
{
991
  int rv;
1029
  int rv = 0;
992
1030
993
  if (self == 0)
1031
  if (self == 0)
994
  {
1032
  {
 Lines 1030-1035    Link Here 
1030
    self->chan_trans_up = 0;
1068
    self->chan_trans_up = 0;
1031
    self->delete_chan_trans = 0;
1069
    self->delete_chan_trans = 0;
1032
  }
1070
  }
1071
1033
  return rv;
1072
  return rv;
1034
}
1073
}
1035
1074
 Lines 1037-1049    Link Here 
1037
int DEFAULT_CC
1076
int DEFAULT_CC
1038
server_begin_update(struct xrdp_mod* mod)
1077
server_begin_update(struct xrdp_mod* mod)
1039
{
1078
{
1040
  struct xrdp_wm* wm;
1079
  struct xrdp_wm* wm = (struct xrdp_wm *)NULL;
1041
  struct xrdp_painter* p;
1080
  struct xrdp_painter* p = (struct xrdp_painter *)NULL;
1042
1081
1043
  wm = (struct xrdp_wm*)(mod->wm);
1082
  wm = (struct xrdp_wm*)(mod->wm);
1044
  p = xrdp_painter_create(wm, wm->session);
1083
  p = xrdp_painter_create(wm, wm->session);
1045
  xrdp_painter_begin_update(p);
1084
  xrdp_painter_begin_update(p);
1046
  mod->painter = (long)p;
1085
  mod->painter = (long)p;
1086
1047
  return 0;
1087
  return 0;
1048
}
1088
}
1049
1089
 Lines 1051-1062    Link Here 
1051
int DEFAULT_CC
1091
int DEFAULT_CC
1052
server_end_update(struct xrdp_mod* mod)
1092
server_end_update(struct xrdp_mod* mod)
1053
{
1093
{
1054
  struct xrdp_painter* p;
1094
  struct xrdp_painter* p = (struct xrdp_painter *)NULL;
1055
1095
1056
  p = (struct xrdp_painter*)(mod->painter);
1096
  p = (struct xrdp_painter*)(mod->painter);
1057
  xrdp_painter_end_update(p);
1097
  xrdp_painter_end_update(p);
1058
  xrdp_painter_delete(p);
1098
  xrdp_painter_delete(p);
1059
  mod->painter = 0;
1099
  mod->painter = 0;
1100
1060
  return 0;
1101
  return 0;
1061
}
1102
}
1062
1103
 Lines 1064-1071    Link Here 
1064
int DEFAULT_CC
1105
int DEFAULT_CC
1065
server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy)
1106
server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy)
1066
{
1107
{
1067
  struct xrdp_wm* wm;
1108
  struct xrdp_wm* wm = (struct xrdp_wm *)NULL;
1068
  struct xrdp_painter* p;
1109
  struct xrdp_painter* p = (struct xrdp_painter *)NULL;
1069
1110
1070
  wm = (struct xrdp_wm*)(mod->wm);
1111
  wm = (struct xrdp_wm*)(mod->wm);
1071
  p = (struct xrdp_painter*)(mod->painter);
1112
  p = (struct xrdp_painter*)(mod->painter);
 Lines 1302-1308    Link Here 
1302
int DEFAULT_CC
1343
int DEFAULT_CC
1303
server_reset(struct xrdp_mod* mod, int width, int height, int bpp)
1344
server_reset(struct xrdp_mod* mod, int width, int height, int bpp)
1304
{
1345
{
1305
  struct xrdp_wm* wm;
1346
  struct xrdp_wm* wm = (struct xrdp_wm *)NULL;
1306
1347
1307
  wm = (struct xrdp_wm*)(mod->wm);
1348
  wm = (struct xrdp_wm*)(mod->wm);
1308
  if (wm->client_info == 0)
1349
  if (wm->client_info == 0)
 Lines 1342-1348    Link Here 
1342
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
1383
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
1343
                     int* channel_flags)
1384
                     int* channel_flags)
1344
{
1385
{
1345
  struct xrdp_wm* wm;
1386
  struct xrdp_wm* wm = (struct xrdp_wm *)NULL;
1346
1387
1347
  wm = (struct xrdp_wm*)(mod->wm);
1388
  wm = (struct xrdp_wm*)(mod->wm);
1348
  if (wm->mm->sesman_controlled)
1389
  if (wm->mm->sesman_controlled)
 Lines 1358-1364    Link Here 
1358
int DEFAULT_CC
1399
int DEFAULT_CC
1359
server_get_channel_id(struct xrdp_mod* mod, char* name)
1400
server_get_channel_id(struct xrdp_mod* mod, char* name)
1360
{
1401
{
1361
  struct xrdp_wm* wm;
1402
  struct xrdp_wm* wm = (struct xrdp_wm *)NULL;
1362
1403
1363
  wm = (struct xrdp_wm*)(mod->wm);
1404
  wm = (struct xrdp_wm*)(mod->wm);
1364
  if (wm->mm->sesman_controlled)
1405
  if (wm->mm->sesman_controlled)
 Lines 1374-1380    Link Here 
1374
                       char* data, int data_len,
1415
                       char* data, int data_len,
1375
                       int total_data_len, int flags)
1416
                       int total_data_len, int flags)
1376
{
1417
{
1377
  struct xrdp_wm* wm;
1418
  struct xrdp_wm* wm = (struct xrdp_wm *)NULL;
1378
1419
1379
  wm = (struct xrdp_wm*)(mod->wm);
1420
  wm = (struct xrdp_wm*)(mod->wm);
1380
  if (wm->mm->sesman_controlled)
1421
  if (wm->mm->sesman_controlled)
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xrdp/xrdp_wm.c (-2 / +18 lines)
 Lines 27-36    Link Here 
27
xrdp_wm_create(struct xrdp_process* owner,
27
xrdp_wm_create(struct xrdp_process* owner,
28
               struct xrdp_client_info* client_info)
28
               struct xrdp_client_info* client_info)
29
{
29
{
30
  struct xrdp_wm* self;
30
  struct xrdp_wm* self = (struct xrdp_wm *)NULL;
31
  char event_name[256];
31
  char event_name[256];
32
  int pid;
32
  int pid = 0;
33
  unsigned int bpp = 0;
33
34
35
  /* initialize (zero out) local variables: */
36
  memset(event_name,0,sizeof(char) * 256);
37
38
  bpp = (client_info->bpp < 32) ? client_info->bpp : 24;
34
  self = (struct xrdp_wm*)g_malloc(sizeof(struct xrdp_wm), 1);
39
  self = (struct xrdp_wm*)g_malloc(sizeof(struct xrdp_wm), 1);
35
  self->client_info = client_info;
40
  self->client_info = client_info;
36
  self->screen = xrdp_bitmap_create(client_info->width,
41
  self->screen = xrdp_bitmap_create(client_info->width,
 Lines 340-345    Link Here 
340
    self->red       = COLOR24BGR(0xff, 0x00, 0x00);
345
    self->red       = COLOR24BGR(0xff, 0x00, 0x00);
341
    self->green     = COLOR24BGR(0x00, 0xff, 0x00);
346
    self->green     = COLOR24BGR(0x00, 0xff, 0x00);
342
  }
347
  }
348
  else if (self->screen->bpp == 32)
349
  {
350
    self->black     = COLOR24BGR(0, 0, 0);
351
    self->grey      = COLOR24BGR(0xc0, 0xc0, 0xc0);
352
    self->dark_grey = COLOR24BGR(0x80, 0x80, 0x80);
353
    self->blue      = COLOR24BGR(0x00, 0x00, 0xff);
354
    self->dark_blue = COLOR24BGR(0x00, 0x00, 0x7f);
355
    self->white     = COLOR24BGR(0xff, 0xff, 0xff);
356
    self->red       = COLOR24BGR(0xff, 0x00, 0x00);
357
    self->green     = COLOR24BGR(0x00, 0xff, 0x00);
358
  }
343
  return 0;
359
  return 0;
344
}
360
}
345
361
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xup/Makefile.am (-2 / +10 lines)
 Lines 1-9    Link Here 
1
1
2
AM_CFLAGS = \
2
AM_CFLAGS = \
3
  -pthread \
3
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
4
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SBIN_PATH=\"${sbindir}\" \
5
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
6
  -DXRDP_PID_PATH=\"${localstatedir}/run\"
7
  -DXRDP_PID_PATH=\"${localstatedir}/run\" \
8
  -D_FILE_OFFSET_BITS=64 \
9
  -D_REENTRANT \
10
  -D_GNU_SOURCE \
11
  -D_XOPEN_SOURCE_EXTENDED
12
13
AM_LDFLAGS = \
14
  -lpthread
7
15
8
INCLUDES = \
16
INCLUDES = \
9
  -I$(top_srcdir)/common
17
  -I$(top_srcdir)/common
 Lines 14-17    Link Here 
14
libxup_la_SOURCES = xup.c
22
libxup_la_SOURCES = xup.c
15
23
16
libxup_la_LIBADD = \
24
libxup_la_LIBADD = \
17
  $(top_srcdir)/common/libcommon.la
25
  $(top_builddir)/common/libcommon.la
(-)xrdp/xrdp-0.5.0~20100303cvs.orig/xup/xup.c (-5 / +5 lines)
 Lines 140-150    Link Here 
140
  mod->server_fill_rect(mod, 0, 0, mod->width, mod->height);
140
  mod->server_fill_rect(mod, 0, 0, mod->width, mod->height);
141
  mod->server_end_update(mod);
141
  mod->server_end_update(mod);
142
  mod->server_msg(mod, "started connecting", 0);
142
  mod->server_msg(mod, "started connecting", 0);
143
  /* only support 8 and 16 bpp connections from rdp client */
143
  /* only support 8, 15, 16, 24 and 32 bpp connections from rdp clients */
144
  if (mod->bpp != 8 && mod->bpp != 16)
144
  if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24 && mod->bpp != 32)
145
  {
145
  {
146
    mod->server_msg(mod,
146
    mod->server_msg(mod,
147
      "error - only supporting 8 and 16 bpp rdp connections", 0);
147
      "ERROR: only 8-, 15-, 16-, 24-, or 32-bpp RDP connections are supported", 0);
148
    LIB_DEBUG(mod, "out lib_mod_connect error");
148
    LIB_DEBUG(mod, "out lib_mod_connect error");
149
    return 1;
149
    return 1;
150
  }
150
  }
 Lines 194-202    Link Here 
194
    g_tcp_close(mod->sck);
194
    g_tcp_close(mod->sck);
195
    mod->sck = 0;
195
    mod->sck = 0;
196
    i++;
196
    i++;
197
    if (i >= 4)
197
    if (i >= 2)
198
    {
198
    {
199
      mod->server_msg(mod, "connect problem, giving up", 0);
199
      mod->server_msg(mod, "connection problem, giving up", 0);
200
      break;
200
      break;
201
    }
201
    }
202
    g_sleep(250);
202
    g_sleep(250);

Return to bug 19953