Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.1 KiB

  1. package Win32::OLE;
  2. sub _croak { require Carp; Carp::croak(@_) }
  3. unless (defined &Dispatch) {
  4. DynaLoader::boot_DynaLoader('DynaLoader')
  5. unless defined(&DynaLoader::dl_load_file);
  6. my $file;
  7. foreach my $dir (@INC) {
  8. my $try = "$dir/auto/Win32/OLE/OLE.dll";
  9. last if $file = (-f $try && $try);
  10. }
  11. _croak("Can't locate loadable object for module Win32::OLE".
  12. " in \@INC (\@INC contains: @INC)")
  13. unless $file; # wording similar to error from 'require'
  14. my $libref = DynaLoader::dl_load_file($file, 0) or
  15. _croak("Can't load '$file' for module Win32::OLE: ".
  16. DynaLoader::dl_error()."\n");
  17. my $boot_symbol_ref = DynaLoader::dl_find_symbol($libref, "boot_Win32__OLE")
  18. or _croak("Can't find 'boot_Win32__OLE' symbol in $file\n");
  19. my $xs = DynaLoader::dl_install_xsub("Win32::OLE::bootstrap",
  20. $boot_symbol_ref, $file);
  21. &$xs('Win32::OLE');
  22. }
  23. if (defined &DB::sub && !defined $_Unique) {
  24. warn "Win32::OLE operating in debugging mode: _Unique => 1\n";
  25. $_Unique = 1;
  26. }
  27. $Warn = 1;
  28. sub CP_ACP {0;} # ANSI codepage
  29. sub CP_OEMCP {1;} # OEM codepage
  30. sub CP_MACCP {2;}
  31. sub CP_UTF7 {65000;}
  32. sub CP_UTF8 {65001;}
  33. sub DISPATCH_METHOD {1;}
  34. sub DISPATCH_PROPERTYGET {2;}
  35. sub DISPATCH_PROPERTYPUT {4;}
  36. sub DISPATCH_PROPERTYPUTREF {8;}
  37. sub COINIT_MULTITHREADED {0;} # Default
  38. sub COINIT_APARTMENTTHREADED {2;} # Use single threaded apartment model
  39. # Bogus COINIT_* values to indicate special cases:
  40. sub COINIT_OLEINITIALIZE {-1;} # Use OleInitialize instead of CoInitializeEx
  41. sub COINIT_NO_INITIALIZE {-2;} # We are already initialized, just believe me
  42. sub HRESULT {
  43. my $hr = shift;
  44. $hr -= 2**32 if $hr & 0x80000000;
  45. return $hr;
  46. }
  47. # CreateObject is defined here only because it is documented in the
  48. # "Learning Perl on Win32 Systems" Gecko book. Please use Win32::OLE->new().
  49. sub CreateObject {
  50. if (ref($_[0]) && UNIVERSAL::isa($_[0],'Win32::OLE')) {
  51. $AUTOLOAD = 'CreateObject';
  52. goto &AUTOLOAD;
  53. }
  54. # Hack to allow C<$obj = CreateObject Win32::OLE 'My.App';>. Although this
  55. # is contrary to the Gecko, we just make it work since it doesn't hurt.
  56. return Win32::OLE->new($_[1]) if $_[0] eq 'Win32::OLE';
  57. # Gecko form: C<$success = Win32::OLE::CreateObject('My.App',$obj);>
  58. $_[1] = Win32::OLE->new($_[0]);
  59. return defined $_[1];
  60. }
  61. sub LastError {
  62. unless (defined $_[0]) {
  63. # Win32::OLE::LastError() will always return $Win32::OLE::LastError
  64. return $LastError;
  65. }
  66. if (ref($_[0]) && UNIVERSAL::isa($_[0],'Win32::OLE')) {
  67. $AUTOLOAD = 'LastError';
  68. goto &AUTOLOAD;
  69. }
  70. #no strict 'refs';
  71. my $LastError = "$_[0]::LastError";
  72. $$LastError = $_[1] if defined $_[1];
  73. return $$LastError;
  74. }
  75. my $Options = "^(?:CP|LCID|Warn|_NewEnum|_Unique)\$";
  76. sub Option {
  77. if (ref($_[0]) && UNIVERSAL::isa($_[0],'Win32::OLE')) {
  78. $AUTOLOAD = 'Option';
  79. goto &AUTOLOAD;
  80. }
  81. my $class = shift;
  82. if (@_ == 1) {
  83. my $option = shift;
  84. return ${"${class}::$option"} if $option =~ /$Options/o;
  85. _croak("Invalid $class option: $option");
  86. }
  87. while (@_) {
  88. my ($option,$value) = splice @_, 0, 2;
  89. _croak("Invalid $class option: $option") if $option !~ /$Options/o;
  90. ${"${class}::$option"} = $value;
  91. $class->_Unique() if $option eq "_Unique";
  92. }
  93. }
  94. sub Invoke {
  95. my ($self,$method,@args) = @_;
  96. $self->Dispatch($method, my $retval, @args);
  97. return $retval;
  98. }
  99. sub LetProperty {
  100. my ($self,$method,@args) = @_;
  101. $self->Dispatch([DISPATCH_PROPERTYPUT, $method], my $retval, @args);
  102. return $retval;
  103. }
  104. sub SetProperty {
  105. my ($self,$method,@args) = @_;
  106. my $wFlags = DISPATCH_PROPERTYPUT;
  107. if (@args) {
  108. # If the value is an object then it will be set by reference!
  109. my $value = $args[-1];
  110. if (UNIVERSAL::isa($value, 'Win32::OLE')) {
  111. $wFlags = DISPATCH_PROPERTYPUTREF;
  112. }
  113. elsif (UNIVERSAL::isa($value,'Win32::OLE::Variant')) {
  114. my $type = $value->Type & ~0xfff; # VT_TYPEMASK
  115. # VT_DISPATCH and VT_UNKNOWN represent COM objects
  116. $wFlags = DISPATCH_PROPERTYPUTREF if $type == 9 || $type == 13;
  117. }
  118. }
  119. $self->Dispatch([$wFlags, $method], my $retval, @args);
  120. return $retval;
  121. }
  122. sub AUTOLOAD {
  123. my $self = shift;
  124. $AUTOLOAD = substr $AUTOLOAD, rindex($AUTOLOAD, ':')+1;
  125. _croak("Cannot autoload class method \"$AUTOLOAD\"")
  126. unless ref($self) && UNIVERSAL::isa($self, 'Win32::OLE');
  127. my $success = $self->Dispatch($AUTOLOAD, my $retval, @_);
  128. unless (defined $success || ($^H & 0x200) != 0) {
  129. # Retry default method if C<no strict 'subs';>
  130. $self->Dispatch(undef, $retval, $AUTOLOAD, @_);
  131. }
  132. return $retval;
  133. }
  134. sub in {
  135. my @res;
  136. while (@_) {
  137. my $this = shift;
  138. if (UNIVERSAL::isa($this, 'Win32::OLE')) {
  139. push @res, Win32::OLE::Enum->All($this);
  140. }
  141. elsif (ref($this) eq 'ARRAY') {
  142. push @res, @$this;
  143. }
  144. else {
  145. push @res, $this;
  146. }
  147. }
  148. return @res;
  149. }
  150. sub valof {
  151. my $arg = shift;
  152. if (UNIVERSAL::isa($arg, 'Win32::OLE')) {
  153. require Win32::OLE::Variant;
  154. my ($class) = overload::StrVal($arg) =~ /^([^=]+)=/;
  155. #no strict 'refs';
  156. local $Win32::OLE::CP = ${"${class}::CP"};
  157. local $Win32::OLE::LCID = ${"${class}::LCID"};
  158. #use strict 'refs';
  159. # VT_EMPTY variant for return code
  160. my $variant = Win32::OLE::Variant->new;
  161. $arg->Dispatch(undef, $variant);
  162. return $variant->Value;
  163. }
  164. $arg = $arg->Value if UNIVERSAL::can($arg, 'Value');
  165. return $arg;
  166. }
  167. sub with {
  168. my $object = shift;
  169. while (@_) {
  170. my $property = shift;
  171. $object->{$property} = shift;
  172. }
  173. }
  174. ########################################################################
  175. package Win32::OLE::Tie;
  176. # Only retry default method under C<no strict 'subs';>
  177. sub FETCH {
  178. my ($self,$key) = @_;
  179. if ($key eq "_NewEnum") {
  180. (my $class = ref $self) =~ s/::Tie$//;
  181. return [Win32::OLE::Enum->All($self)] if ${"${class}::_NewEnum"};
  182. }
  183. $self->Fetch($key, !$Win32::OLE::Strict);
  184. }
  185. sub STORE {
  186. my ($self,$key,$value) = @_;
  187. $self->Store($key, $value, !$Win32::OLE::Strict);
  188. }
  189. 1;