Index: /CKEditor/trunk/CHANGES.html
===================================================================
--- /CKEditor/trunk/CHANGES.html	(revision 5681)
+++ /CKEditor/trunk/CHANGES.html	(revision 5682)
@@ -63,4 +63,5 @@
 		<li><a href="http://dev.fckeditor.net/ticket/5951">#5951</a> : Avoid problems with security systems due to the usage of UniversalXPConnect.</li>
 		<li><a href="http://dev.fckeditor.net/ticket/5441">#5441</a> : Avoid errors if the editor instance is removed from the DOM before calling its destroy() method.</li>
+		<li><a href="http://dev.fckeditor.net/ticket/4997">#4997</a> : Provide better access to the native input in the ui.dialog.file element.</li>
 	</ul>
 	<h3>
Index: /CKEditor/trunk/_source/plugins/dialogui/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/dialogui/plugin.js	(revision 5681)
+++ /CKEditor/trunk/_source/plugins/dialogui/plugin.js	(revision 5682)
@@ -1324,7 +1324,38 @@
 				 * @example
 				 */
-				getAction : function( action )
+				getAction : function()
 				{
 					return this.getInputElement().getParent().$.action;
+				},
+
+				/**
+				 * The events must be applied on the inner input element, and
+				 * that must be done when the iframe & form has been loaded
+				 */
+				registerEvents : function( definition )
+				{
+					var regex = /^on([A-Z]\w+)/,
+						match;
+
+					var registerDomEvent = function( uiElement, dialog, eventName, func )
+					{
+						uiElement.on( 'formLoaded', function()
+						{
+							uiElement.getInputElement().on( eventName, func, uiElement );
+						});
+					};
+
+					for ( var i in definition )
+					{
+						if ( !( match = i.match( regex ) ) )
+							continue;
+
+						if ( this.eventProcessors[i] )
+							this.eventProcessors[i].call( this, this._.dialog, definition[i] );
+						else
+							registerDomEvent( this, this._.dialog, match[1].toLowerCase(), definition[i] );
+					}
+
+					return this;
 				},
 
@@ -1340,5 +1371,32 @@
 						frameDocument = frameElement.getFrameDocument(),
 						elementDefinition = this._.definition,
-						buttons = this._.buttons;
+						buttons = this._.buttons,
+						callNumber = this.formLoadedNumber,
+						unloadNumber = this.formUnloadNumber;
+
+					// The callback function for the iframe, but we must call tools.addFunction only once
+					// so we store the function number in this.formLoadedNumber
+					if (!callNumber)
+					{
+						callNumber = this.formLoadedNumber = CKEDITOR.tools.addFunction(
+							function()
+							{
+								// Now we can apply the events to the input type=file
+								this.fire( 'formLoaded' ) ;
+							}, this ) ;
+
+						// Remove listeners attached to the content of the iframe (the file input)
+						unloadNumber = this.formUnloadNumber = CKEDITOR.tools.addFunction(
+							function()
+							{
+								this.getInputElement().clearCustomData();
+							}, this ) ;
+
+						this.getDialog()._.editor.on( 'destroy', function()
+								{
+									CKEDITOR.tools.removeFunction( callNumber );
+									CKEDITOR.tools.removeFunction( unloadNumber );
+								} );
+					}
 
 					function generateFormField()
@@ -1364,5 +1422,7 @@
 								'" />',
 								'</form>',
-								'</body></html>' ].join( '' ) );
+								'</body></html>',
+								'<script>window.parent.CKEDITOR.tools.callFunction(' + callNumber + ');',
+								'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber + ')}</script>' ].join( '' ) );
 
 						frameDocument.$.close();
@@ -1381,8 +1441,16 @@
 				getValue : function()
 				{
-					// The file path returned from the input tag is incomplete anyway, so it's
-					// safe to ignore it and prevent the confirmation dialog from appearing.
-					// (Part of #3465)
-					return '';
+					return this.getInputElement().$.value;
+				},
+
+				/***
+				 * The default value of input type="file" is an empty string, but during initialization
+				 * of this UI element, the iframe still isn't ready so it can't be read from that object
+				 * Setting it manually prevents later issues about the current value ("") being different
+				 * of the initial value (undefined as it asked for .value of a div)
+				 */
+				setInitValue : function()
+				{
+					this._.initValue = '';
 				},
 
@@ -1393,5 +1461,25 @@
 				 * @example
 				 */
-				eventProcessors : commonEventProcessors,
+				eventProcessors :
+				{
+					onChange : function( dialog, func )
+					{
+						// If this method is called several times (I'm not sure about how this can happen but the default
+						// onChange processor includes this protection)
+						// In order to reapply to the new element, the property is deleted at the beggining of the registerEvents method
+						if ( !this._.domOnChangeRegistered )
+						{
+							// By listening for the formLoaded event, this handler will get reapplied when a new
+							// form is created
+							this.on( 'formLoaded', function()
+							{
+								this.getInputElement().on( 'change', function(){ this.fire( 'change', { value : this.getValue() } ); }, this );
+							}, this );
+							this._.domOnChangeRegistered = true;
+						}
+
+						this.on( 'change', func );
+					}
+				},
 
 				keyboardFocusable : true
